file.close()
-def make_binding_header():
- now = datetime.datetime.now()
-
- file = open('include\\binding.h', 'w')
- file.write('#define PCI_VENDOR_ID\t' + '0x' + os.environ['PCI_VENDOR_ID'] + '\n')
- file.write('\n')
-
- file.write('#define PCI_DEVICE_ID\t' + '0x' + os.environ['PCI_DEVICE_ID'] + '\n')
- file.write('\n')
-
- file.write('#define PCI_REVISION\t' + '0x' + os.environ['PCI_REVISION'] + '\n')
- file.write('\n')
-
- file.close()
-
-
def copy_inf(name):
src = open('src\\%s.inf' % name, 'r')
dst = open('proj\\%s.inf' % name, 'w')
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)
- line = re.sub('@PCI_VENDOR_ID@', os.environ['PCI_VENDOR_ID'], line)
- line = re.sub('@PCI_DEVICE_ID@', os.environ['PCI_DEVICE_ID'], line)
- line = re.sub('@PCI_REVISION@', os.environ['PCI_REVISION'], line)
dst.write(line)
dst.close()
make_version_header()
- os.environ['PCI_VENDOR_ID'] = '5853'
- os.environ['PCI_DEVICE_ID'] = '0002'
- os.environ['PCI_REVISION'] = '02'
-
- make_binding_header()
-
copy_inf(driver)
symstore_del(driver, 30)
+++ /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 _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 \
- ) \
- )
-
-typedef struct _XENFILT_EMULATED_CONTEXT XENFILT_EMULATED_CONTEXT, *PXENFILT_EMULATED_CONTEXT;
-
-#define EMULATED_OPERATION(_Type, _Name, _Arguments) \
- _Type (*EMULATED_ ## _Name) _Arguments;
-
-typedef struct _XENFILT_EMULATED_OPERATIONS {
- DEFINE_EMULATED_OPERATIONS
-} XENFILT_EMULATED_OPERATIONS, *PXENFILT_EMULATED_OPERATIONS;
-
-#undef EMULATED_OPERATION
-
-typedef struct _XENFILT_EMULATED_INTERFACE XENFILT_EMULATED_INTERFACE, *PXENFILT_EMULATED_INTERFACE;
-
-// {062AAC96-2BF8-4A69-AD6B-154CF051E977}
-DEFINE_GUID(GUID_EMULATED_INTERFACE,
- 0x62aac96,
- 0x2bf8,
- 0x4a69,
- 0xad,
- 0x6b,
- 0x15,
- 0x4c,
- 0xf0,
- 0x51,
- 0xe9,
- 0x77);
-
-#define EMULATED_INTERFACE_VERSION 3
-
-#define EMULATED_OPERATIONS(_Interface) \
- (PXENFILT_EMULATED_OPERATIONS *)((ULONG_PTR)(_Interface))
-
-#define EMULATED_CONTEXT(_Interface) \
- (PXENFILT_EMULATED_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID))
-
-#define EMULATED(_Operation, _Interface, ...) \
- (*EMULATED_OPERATIONS(_Interface))->EMULATED_ ## _Operation((*EMULATED_CONTEXT(_Interface)), __VA_ARGS__)
-
-#endif // _XENFILT_EMULATED_INTERFACE_H
-
+++ /dev/null
-#!/bin/sh -x
-
-REPO="$1"
-TAG="$2"
-
-copy()
-{
- SRCDIR="$1"
- DSTDIR="$2"
- HEADER="$3"
-
- CWD=$(pwd)
-
- mkdir -p ${DSTDIR}
- cd ${DSTDIR}
-
- URL="${REPO}/raw-file/${TAG}/xen/include/${SRCDIR}/${HEADER}"
-
- wget ${URL}
-
- mv ${HEADER} ${HEADER}.orig
- sed -e 's/ unsigned long/ ULONG_PTR/g' \
- -e 's/(unsigned long/(ULONG_PTR/g' \
- -e 's/ long/ LONG_PTR/g' \
- -e 's/(long/(LONG_PTR/g' \
- < ${HEADER}.orig > ${HEADER}
-
- cd ${CWD}
-}
-
-rm -rf xen
-mkdir -p xen
-cd xen
-
-copy public . xen.h
-copy public . xen-compat.h
-copy public . trace.h
-copy public . memory.h
-copy public . sched.h
-copy public . event_channel.h
-copy public . grant_table.h
-copy xen . errno.h
-
-copy public/arch-x86 arch-x86 xen.h
-copy public/arch-x86 arch-x86 xen-x86_32.h
-copy public/arch-x86 arch-x86 xen-x86_64.h
-
-copy public/hvm hvm hvm_op.h
-copy public/hvm hvm params.h
-
-copy public/io io xs_wire.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>
-
-#include "assert.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;
-}
-
-typedef struct _NON_PAGED_BUFFER_HEADER {
- SIZE_T Length;
- ULONG Tag;
-} NON_PAGED_BUFFER_HEADER, *PNON_PAGED_BUFFER_HEADER;
-
-typedef struct _NON_PAGED_BUFFER_TRAILER {
- ULONG Tag;
-} NON_PAGED_BUFFER_TRAILER, *PNON_PAGED_BUFFER_TRAILER;
-
-static FORCEINLINE PVOID
-__AllocateNonPagedPoolWithTag(
- IN SIZE_T Length,
- IN ULONG Tag
- )
-{
- PUCHAR Buffer;
- PNON_PAGED_BUFFER_HEADER Header;
- PNON_PAGED_BUFFER_TRAILER Trailer;
-
- ASSERT(Length != 0);
-
- Buffer = ExAllocatePoolWithTag(NonPagedPool,
- sizeof (NON_PAGED_BUFFER_HEADER) +
- Length +
- sizeof (NON_PAGED_BUFFER_TRAILER),
- Tag);
- if (Buffer == NULL)
- goto done;
-
- RtlZeroMemory(Buffer,
- sizeof (NON_PAGED_BUFFER_HEADER) +
- Length +
- sizeof (NON_PAGED_BUFFER_TRAILER));
-
- Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
- Header->Length = Length;
- Header->Tag = Tag;
-
- Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
-
- Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
- Trailer->Tag = Tag;
-
-done:
- return Buffer;
-}
-
-static FORCEINLINE VOID
-__FreePoolWithTag(
- IN PVOID _Buffer,
- IN ULONG Tag
- )
-{
- PUCHAR Buffer = _Buffer;
- SIZE_T Length;
- PNON_PAGED_BUFFER_HEADER Header;
- PNON_PAGED_BUFFER_TRAILER Trailer;
-
- ASSERT(Buffer != NULL);
-
- Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
-
- Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
- ASSERT3U(Tag, ==, Header->Tag);
- Length = Header->Length;
-
- Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
-
- Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
- ASSERT3U(Tag, ==, Trailer->Tag);
-
- Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
-
- RtlFillMemory(Buffer,
- sizeof (NON_PAGED_BUFFER_HEADER) +
- Length +
- sizeof (NON_PAGED_BUFFER_TRAILER),
- 0xAA);
-
- ExFreePoolWithTag(Buffer, Tag);
-}
-
-#endif // _UTIL_H
VOID
);
-// LOG
+// MODULE
XEN_API
VOID
-LogXenCchVPrintf(
- IN ULONG Count,
- IN const CHAR *Format,
- IN va_list Arguments
+ModuleLookup(
+ IN ULONG_PTR Address,
+ OUT PCHAR *Name,
+ OUT PULONG_PTR Offset
);
-XEN_API
-VOID
-LogXenCchPrintf(
- IN ULONG Count,
- IN const CHAR *Format,
- ...
- );
+// LOG
-XEN_API
-VOID
-LogXenVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- );
+typedef enum _LOG_LEVEL {
+ LOG_LEVEL_INVALID = 0,
+ LOG_LEVEL_TRACE = 1 << DPFLTR_TRACE_LEVEL,
+ LOG_LEVEL_INFO = 1 << DPFLTR_INFO_LEVEL,
+ LOG_LEVEL_WARNING = 1 << DPFLTR_WARNING_LEVEL,
+ LOG_LEVEL_ERROR = 1 << DPFLTR_ERROR_LEVEL,
+ LOG_LEVEL_CRITICAL = 0x80000000
+} LOG_LEVEL, *PLOG_LEVEL;
XEN_API
VOID
-LogXenPrintf(
+LogCchVPrintf(
+ IN LOG_LEVEL Level,
+ IN ULONG Count,
IN const CHAR *Format,
- ...
+ IN va_list Arguments
);
XEN_API
VOID
-LogQemuCchVPrintf(
- IN ULONG Count,
+LogVPrintf(
+ IN LOG_LEVEL Level,
IN const CHAR *Format,
IN va_list Arguments
);
XEN_API
VOID
-LogQemuCchPrintf(
+LogCchPrintf(
+ IN LOG_LEVEL Level,
IN ULONG Count,
IN const CHAR *Format,
...
XEN_API
VOID
-LogQemuVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- );
-
-XEN_API
-VOID
-LogQemuPrintf(
+LogPrintf(
+ IN LOG_LEVEL Level,
IN const CHAR *Format,
...
);
-XEN_API
-VOID
-LogEnable(
- VOID
- );
-
-XEN_API
-VOID
-LogDisable(
- VOID
- );
-
-// UNPLUG
-
-XEN_API
-NTSTATUS
-UnplugReference(
- VOID
- );
-
-XEN_API
-VOID
-UnplugDereference(
- VOID
- );
-
-XEN_API
-NTSTATUS
-UnplugDevice(
- PCHAR Class,
- PCHAR Device
- );
-
-XEN_API
-VOID
-UnplugReplay(
- VOID
- );
-
-// MODULE
-
-XEN_API
-VOID
-ModuleLookup(
- IN ULONG_PTR Address,
- OUT PCHAR *Name,
- OUT PULONG_PTR Offset
- );
-
#endif // _XEN_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">
<Import Project="..\configs.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+ <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableInf2cat>false</EnableInf2cat>
<IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
<ClCompile Include="..\..\src\xen\memory.c" />
<ClCompile Include="..\..\src\xen\sched.c" />
<ClCompile Include="..\..\src\xen\log.c" />
- <ClCompile Include="..\..\src\xen\debug.c" />
- <ClCompile Include="..\..\src\xen\dump.c" />
+ <ClCompile Include="..\..\src\xen\bug_check.c" />
<ClCompile Include="..\..\src\xen\module.c" />
<ClCompile Include="..\..\src\xen\process.c" />
- <ClCompile Include="..\..\src\xen\unplug.c" />
<ClCompile Include="..\..\src\xen\system.c" />
</ItemGroup>
<ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+ <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableInf2cat>false</EnableInf2cat>
<IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="..\..\src\common\registry.c" />
<ClCompile Include="..\..\src\xenbus\bus.c" />
<ClCompile Include="..\..\src\xenbus\dma.c" />
<ClCompile Include="..\..\src\xenbus\debug.c" />
<ClCompile Include="..\..\src\xenbus\fdo.c" />
<ClCompile Include="..\..\src\xenbus\gnttab.c" />
<ClCompile Include="..\..\src\xenbus\pdo.c" />
- <ClCompile Include="..\..\src\xenbus\registry.c" />
<ClCompile Include="..\..\src\xenbus\shared_info.c" />
<ClCompile Include="..\..\src\xenbus\store.c" />
<ClCompile Include="..\..\src\xenbus\suspend.c" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <IncludePath>..\..\include;$(IncludePath)</IncludePath>
+ <IncludePath>..\..\include;..\..\src\common;$(IncludePath)</IncludePath>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableInf2cat>false</EnableInf2cat>
<IntDir>..\$(ProjectName)\$(ConfigurationName)\$(Platform)\</IntDir>
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="../../src/common/registry.c" />
<ClCompile Include="../../src/xenfilt/driver.c" />
<ClCompile Include="../../src/xenfilt/fdo.c" />
- <ClCompile Include="../../src/xenfilt/emulated.c" />
<ClCompile Include="../../src/xenfilt/pdo.c" />
- <ClCompile Include="../../src/xenfilt/registry.c" />
<ClCompile Include="../../src/xenfilt/thread.c" />
</ItemGroup>
<ItemGroup>
#include <stdlib.h>
#include <strsafe.h>
#include <malloc.h>
+#include <assert.h>
#include <version.h>
#define MAXIMUM_BUFFER_SIZE 1024
+#define ENUM_KEY "SYSTEM\\CurrentControlSet\\Enum"
+
+#define CLASS_KEY "SYSTEM\\CurrentControlSet\\Control\\Class"
+
+#define SERVICE_KEY(_Name) "SYSTEM\\CurrentControlSet\\Services\\" ## _Name
+#define PARAMETERS_KEY(_Name) SERVICE_KEY(_Name) ## "\\Parameters"
+
static VOID
#pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
__Log(
Category = TXTLOG_VENDOR;
Flags = TXTLOG_DETAILS;
- SetupWriteTextLog(LogToken, Category, Flags, Buffer);
- Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+ SetupWriteTextLog(LogToken, Category, Flags, Buffer);
+ Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+
+ __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
+ __analysis_assume(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
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenEnumKey(
+ OUT PHKEY Key
+ )
+{
+ HRESULT Error;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ ENUM_KEY,
+ 0,
+ KEY_READ,
+ Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ return TRUE;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenPciKey(
+ OUT PHKEY Key
+ )
+{
+ BOOLEAN Success;
+ HKEY EnumKey;
+ HRESULT Error;
+
+ Success = OpenEnumKey(&EnumKey);
+ if (!Success)
+ goto fail1;
+
+ Error = RegOpenKeyEx(EnumKey,
+ "PCI",
+ 0,
+ KEY_READ,
+ Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ RegCloseKey(EnumKey);
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(EnumKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+GetDeviceKeyName(
+ IN PTCHAR Prefix,
+ OUT PTCHAR *Name
+ )
+{
+ BOOLEAN Success;
+ HKEY PciKey;
+ HRESULT Error;
+ DWORD SubKeys;
+ DWORD MaxSubKeyLength;
+ DWORD SubKeyLength;
+ PTCHAR SubKeyName;
+ DWORD Index;
+
+ Success = OpenPciKey(&PciKey);
+ if (!Success)
+ goto fail1;
+
+ Error = RegQueryInfoKey(PciKey,
+ NULL,
+ NULL,
+ NULL,
+ &SubKeys,
+ &MaxSubKeyLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+ SubKeyName = malloc(SubKeyLength);
+ if (SubKeyName == NULL)
+ goto fail3;
+
+ for (Index = 0; Index < SubKeys; Index++) {
+ SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+ memset(SubKeyName, 0, SubKeyLength);
+
+ Error = RegEnumKeyEx(PciKey,
+ Index,
+ (LPTSTR)SubKeyName,
+ &SubKeyLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail4;
+ }
+
+ if (strncmp(SubKeyName, Prefix, strlen(Prefix)) == 0)
+ goto found;
+ }
+
+ free(SubKeyName);
+ SubKeyName = NULL;
+
+found:
+ RegCloseKey(PciKey);
+
+ Log("%s", (SubKeyName != NULL) ? SubKeyName : "none found");
+
+ *Name = SubKeyName;
+ return TRUE;
+
+fail4:
+ Log("fail4");
+
+ free(SubKeyName);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(PciKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+#define PLATFORM_DEVICE_0001_NAME "VEN_5853&DEV_0001"
+#define PLATFORM_DEVICE_0002_NAME "VEN_5853&DEV_0002"
+
+#define XENSERVER_VENDOR_DEVICE_NAME "VEN_5853&DEV_C000"
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenDeviceKey(
+ IN PTCHAR Name,
+ OUT PHKEY Key
+ )
+{
+ BOOLEAN Success;
+ HKEY PciKey;
+ HRESULT Error;
+
+ Success = OpenPciKey(&PciKey);
+ if (!Success)
+ goto fail1;
+
+ Error = RegOpenKeyEx(PciKey,
+ Name,
+ 0,
+ KEY_READ,
+ Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ RegCloseKey(PciKey);
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(PciKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+
+static DECLSPEC_NOINLINE BOOLEAN
+GetDriverKeyName(
+ IN HKEY DeviceKey,
+ OUT PTCHAR *Name
+ )
+{
+ HRESULT Error;
+ DWORD SubKeys;
+ DWORD MaxSubKeyLength;
+ DWORD SubKeyLength;
+ PTCHAR SubKeyName;
+ DWORD Index;
+ HKEY SubKey;
+ PTCHAR DriverKeyName;
+
+ Error = RegQueryInfoKey(DeviceKey,
+ NULL,
+ NULL,
+ NULL,
+ &SubKeys,
+ &MaxSubKeyLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+
+ SubKeyName = malloc(SubKeyLength);
+ if (SubKeyName == NULL)
+ goto fail2;
+
+ SubKey = NULL;
+ DriverKeyName = NULL;
+
+ for (Index = 0; Index < SubKeys; Index++) {
+ DWORD MaxValueLength;
+ DWORD DriverKeyNameLength;
+ DWORD Type;
+
+ SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
+ memset(SubKeyName, 0, SubKeyLength);
+
+ Error = RegEnumKeyEx(DeviceKey,
+ Index,
+ (LPTSTR)SubKeyName,
+ &SubKeyLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ Error = RegOpenKeyEx(DeviceKey,
+ SubKeyName,
+ 0,
+ KEY_READ,
+ &SubKey);
+ if (Error != ERROR_SUCCESS)
+ continue;
+
+ Error = RegQueryInfoKey(SubKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail4;
+ }
+
+ DriverKeyNameLength = MaxValueLength + sizeof (TCHAR);
+
+ DriverKeyName = malloc(DriverKeyNameLength);
+ if (DriverKeyName == NULL)
+ goto fail5;
+
+ Error = RegQueryValueEx(SubKey,
+ "Driver",
+ NULL,
+ &Type,
+ (LPBYTE)DriverKeyName,
+ &DriverKeyNameLength);
+ if (Error == ERROR_SUCCESS &&
+ Type == REG_SZ)
+ break;
+
+ free(DriverKeyName);
+ DriverKeyName = NULL;
+
+ RegCloseKey(SubKey);
+ SubKey = NULL;
+ }
+
+ Log("%s", (DriverKeyName != NULL) ? DriverKeyName : "none found");
+
+ if (SubKey != NULL)
+ RegCloseKey(SubKey);
+
+ free(SubKeyName);
+
+ *Name = DriverKeyName;
+ return TRUE;
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ if (SubKey != NULL)
+ RegCloseKey(SubKey);
+
+fail3:
+ Log("fail3");
+
+ free(SubKeyName);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenClassKey(
+ OUT PHKEY Key
+ )
+{
+ HRESULT Error;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ CLASS_KEY,
+ 0,
+ KEY_READ,
+ Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ return TRUE;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static DECLSPEC_NOINLINE BOOLEAN
+OpenDriverKey(
+ IN PTCHAR Name,
+ OUT PHKEY Key
+ )
+{
+ BOOLEAN Success;
+ HKEY ClassKey;
+ HRESULT Error;
+
+ Success = OpenClassKey(&ClassKey);
+ if (!Success)
+ goto fail1;
+
+ Error = RegOpenKeyEx(ClassKey,
+ Name,
+ 0,
+ KEY_READ,
+ Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ RegCloseKey(ClassKey);
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(ClassKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static PTCHAR
+GetDeviceInstance(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData
+ )
+{
+ DWORD DeviceInstanceLength;
+ PTCHAR DeviceInstance;
+ DWORD Index;
+ HRESULT Error;
+
+ if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
+ DeviceInfoData,
+ NULL,
+ 0,
+ &DeviceInstanceLength)) {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ goto fail1;
+ }
+
+ DeviceInstanceLength += sizeof (TCHAR);
+
+ DeviceInstance = malloc(DeviceInstanceLength);
+ if (DeviceInstance == NULL)
+ goto fail2;
+
+ memset(DeviceInstance, 0, DeviceInstanceLength);
+
+ if (!SetupDiGetDeviceInstanceId(DeviceInfoSet,
+ DeviceInfoData,
+ DeviceInstance,
+ DeviceInstanceLength,
+ NULL))
+ goto fail3;
+
+ for (Index = 0; Index < strlen(DeviceInstance); Index++)
+ DeviceInstance[Index] = (CHAR)toupper(DeviceInstance[Index]);
+
+ Log("%s", DeviceInstance);
+
+ return DeviceInstance;
+
+fail3:
+ Log("fail3");
+
+ free(DeviceInstance);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return NULL;
+}
+
+static BOOLEAN
+GetActiveDeviceInstance(
+ OUT PTCHAR *DeviceInstance
+ )
+{
+ HKEY ParametersKey;
+ DWORD MaxValueLength;
+ DWORD ActiveDeviceInstanceLength;
+ PTCHAR ActiveDeviceInstance;
+ DWORD Type;
+ HRESULT Error;
+
+ Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ PARAMETERS_KEY("XENBUS"),
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &ParametersKey,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegQueryInfoKey(ParametersKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ ActiveDeviceInstanceLength = MaxValueLength + sizeof (TCHAR);
+
+ ActiveDeviceInstance = malloc(ActiveDeviceInstanceLength);
+ if (ActiveDeviceInstance == NULL)
+ goto fail3;
+
+ memset(ActiveDeviceInstance, 0, ActiveDeviceInstanceLength);
+
+ Error = RegQueryValueEx(ParametersKey,
+ "ActiveDeviceInstance",
+ NULL,
+ &Type,
+ (LPBYTE)ActiveDeviceInstance,
+ &ActiveDeviceInstanceLength);
+ if (Error == ERROR_SUCCESS &&
+ Type == REG_SZ)
+ goto found;
+
+ free(ActiveDeviceInstance);
+ ActiveDeviceInstance = NULL;
+
+found:
+ Log("%s", (ActiveDeviceInstance != NULL) ? ActiveDeviceInstance : "none found");
+
+ RegCloseKey(ParametersKey);
+
+ *DeviceInstance = ActiveDeviceInstance;
+ return TRUE;
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(ParametersKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+SetActiveDeviceInstance(
+ IN PTCHAR DeviceInstance
+ )
+{
+ PTCHAR DeviceName;
+ BOOLEAN Success;
+ HKEY ParametersKey;
+ HRESULT Error;
+
+ Log("%s", DeviceInstance);
+
+ DeviceName = strchr(DeviceInstance, '\\');
+ assert(DeviceName != NULL);
+ DeviceName++;
+
+ // Check whether we are binding to the XenServer vendor device
+ if (strncmp(DeviceName,
+ XENSERVER_VENDOR_DEVICE_NAME,
+ strlen(XENSERVER_VENDOR_DEVICE_NAME)) != 0) {
+ PTCHAR DeviceKeyName;
+
+ // We are binding to a legacy platform device so only make it
+ // active if there is no XenServer vendor device
+ Success = GetDeviceKeyName(XENSERVER_VENDOR_DEVICE_NAME,
+ &DeviceKeyName);
+ if (!Success)
+ goto fail1;
+
+ if (DeviceKeyName != NULL) {
+ Log("ignoring");
+ free(DeviceKeyName);
+ goto done;
+ }
+ }
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ PARAMETERS_KEY("XENBUS"),
+ 0,
+ KEY_ALL_ACCESS,
+ &ParametersKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ Error = RegSetValueEx(ParametersKey,
+ "ActiveDeviceInstance",
+ 0,
+ REG_SZ,
+ (LPBYTE)DeviceInstance,
+ (DWORD)(strlen(DeviceInstance) + sizeof (TCHAR)));
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ RegCloseKey(ParametersKey);
+
+done:
+ return TRUE;
+
+fail3:
+ Log("fail3");
+
+ RegCloseKey(ParametersKey);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+ClearActiveDeviceInstance(
+ VOID
+ )
+{
+ HKEY ParametersKey;
+ HRESULT Error;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ PARAMETERS_KEY("XENBUS"),
+ 0,
+ KEY_ALL_ACCESS,
+ &ParametersKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegDeleteValue(ParametersKey,
+ "ActiveDeviceInstance");
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ RegCloseKey(ParametersKey);
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(ParametersKey);
+
+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:
+ Log("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 WORD DeviceId,
+ IN BOOLEAN Active
+ )
+{
+ TCHAR FriendlyName[MAX_PATH];
+ DWORD FriendlyNameLength;
+ HRESULT Result;
+ HRESULT Error;
+
+ Result = StringCbPrintf(FriendlyName,
+ MAX_PATH,
+ "XenServer PV Bus (%04X) %s",
+ DeviceId,
+ (Active)? "[ACTIVE]" : "");
+ if (!SUCCEEDED(Result))
+ goto fail1;
+
+ Log("%s", FriendlyName);
+
+ FriendlyNameLength = (DWORD)(strlen(FriendlyName) + sizeof (TCHAR));
+
+ if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_FRIENDLYNAME,
+ (PBYTE)FriendlyName,
+ FriendlyNameLength))
+ goto fail2;
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+AllowInstall(
+ VOID
+ )
+{
+ BOOLEAN Success;
+ PTCHAR DeviceKeyName = NULL;
+ HKEY DeviceKey = NULL;
+ PTCHAR DriverKeyName = NULL;
+ HKEY DriverKey = NULL;
+ HRESULT Error;
+ DWORD MaxValueLength;
+ DWORD DriverDescLength;
+ PTCHAR DriverDesc = NULL;
+ DWORD Type;
+
+ // Look for a legacy platform device
+ Success = GetDeviceKeyName(PLATFORM_DEVICE_0001_NAME,
+ &DeviceKeyName);
+ if (!Success)
+ goto fail1;
+
+ if (DeviceKeyName != NULL)
+ goto found;
+
+ Success = GetDeviceKeyName(PLATFORM_DEVICE_0002_NAME,
+ &DeviceKeyName);
+ if (!Success)
+ goto fail2;
+
+ if (DeviceKeyName != NULL)
+ goto found;
+
+ // No legacy platform device
+ goto done;
+
+found:
+ Success = OpenDeviceKey(DeviceKeyName, &DeviceKey);
+ if (!Success)
+ goto fail3;
+
+ // Check for a bound driver
+ Success = GetDriverKeyName(DeviceKey, &DriverKeyName);
+ if (!Success)
+ goto fail4;
+
+ if (DriverKeyName == NULL)
+ goto done;
+
+ Success = OpenDriverKey(DriverKeyName, &DriverKey);
+ if (!Success)
+ goto fail5;
+
+ Error = RegQueryInfoKey(DriverKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail6;
+ }
+
+ DriverDescLength = MaxValueLength + sizeof (TCHAR);
+
+ DriverDesc = malloc(DriverDescLength);
+ if (DriverDesc == NULL)
+ goto fail7;
+
+ memset(DriverDesc, 0, DriverDescLength);
+
+ Error = RegQueryValueEx(DriverKey,
+ "DriverDesc",
+ NULL,
+ &Type,
+ (LPBYTE)DriverDesc,
+ &DriverDescLength);
+ if (Error != ERROR_SUCCESS) {
+ if (Error == ERROR_FILE_NOT_FOUND)
+ goto done;
+
+ SetLastError(Error);
+ goto fail8;
+ }
+
+ if (Type != REG_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail9;
+ }
+
+ if (strcmp(DriverDesc, "XenServer PV Bus") != 0) {
+ SetLastError(ERROR_INSTALL_FAILURE);
+ goto fail10;
+ }
+
+done:
+ if (DriverDesc != NULL) {
+ free(DriverDesc);
+ RegCloseKey(DriverKey);
+ }
+
+ if (DriverKeyName != NULL) {
+ free(DriverKeyName);
+ RegCloseKey(DeviceKey);
+ }
+
+ if (DeviceKeyName != NULL)
+ free(DeviceKeyName);
+
+ return TRUE;
+
+fail10:
+ Log("fail10");
+
+fail9:
+ Log("fail9");
+
+fail8:
+ Log("fail8");
+
+ free(DriverDesc);
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+ RegCloseKey(DriverKey);
+
+fail5:
+ Log("fail5");
- __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
- __analysis_assume(Length >= 2);
- Buffer[Length] = '\0';
- Buffer[Length - 1] = '\n';
- Buffer[Length - 2] = '\r';
+ free(DriverKeyName);
- OutputDebugString(Buffer);
-}
+fail4:
+ Log("fail4");
-#define Log(_Format, ...) \
- __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
+ RegCloseKey(DeviceKey);
-static PTCHAR
-GetErrorMessage(
- IN DWORD Error
- )
-{
- PTCHAR Message;
- ULONG Index;
+fail3:
+ Log("fail3");
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- Error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR)&Message,
- 0,
- NULL);
+ free(DeviceKeyName);
- for (Index = 0; Message[Index] != '\0'; Index++) {
- if (Message[Index] == '\r' || Message[Index] == '\n') {
- Message[Index] = '\0';
- break;
- }
- }
+fail2:
+ Log("fail2");
- return Message;
-}
+fail1:
+ Error = GetLastError();
-static const CHAR *
-FunctionName(
- IN DI_FUNCTION Function
- )
-{
-#define _NAME(_Function) \
- case DIF_ ## _Function: \
- return #_Function;
+ {
+ PTCHAR Message;
- 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;
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
}
- return "UNKNOWN";
-
-#undef _NAME
+ return FALSE;
}
static BOOLEAN
IN PCOINSTALLER_CONTEXT_DATA Context
)
{
- UNREFERENCED_PARAMETER(DeviceInfoSet);
- UNREFERENCED_PARAMETER(DeviceInfoData);
+ BOOLEAN Success;
+ PTCHAR DeviceInstance;
+ PTCHAR ActiveDeviceInstance;
+ HRESULT Error;
+
UNREFERENCED_PARAMETER(Context);
- Log("<===>");
+ Log("====>");
- return ERROR_DI_POSTPROCESSING_REQUIRED;
+ Success = AllowInstall();
+ if (!Success)
+ goto fail1;
+
+ DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+ if (DeviceInstance == NULL)
+ goto fail2;
+
+ ActiveDeviceInstance = NULL;
+
+ Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+ if (!Success)
+ goto fail3;
+
+ if (ActiveDeviceInstance == NULL) {
+ Success = SetActiveDeviceInstance(DeviceInstance);
+ if (!Success)
+ goto fail4;
+ } else {
+ free(ActiveDeviceInstance);
+ }
+
+ free(DeviceInstance);
+
+ Log("<====");
+
+ return ERROR_DI_POSTPROCESSING_REQUIRED;
+
+fail4:
+ Log("fail4");
+
+ free(ActiveDeviceInstance);
+
+fail3:
+ Log("fail3");
+
+ free(DeviceInstance);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
}
static FORCEINLINE HRESULT
)
{
HRESULT Error;
+ PTCHAR DeviceInstance;
+ PTCHAR ActiveDeviceInstance;
+ DWORD DeviceId;
+ BOOLEAN Active;
BOOLEAN Success;
Log("====>");
goto fail1;
}
+ DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+ if (DeviceInstance == NULL)
+ goto fail2;
+
+ ActiveDeviceInstance = NULL;
+
+ Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+ if (!Success)
+ goto fail3;
+
+ if (sscanf_s(DeviceInstance,
+ "PCI\\VEN_5853&DEV_%x",
+ &DeviceId) != 1) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail4;
+ }
+
+ Active = (ActiveDeviceInstance != NULL &&
+ strcmp(DeviceInstance, ActiveDeviceInstance) == 0) ?
+ TRUE :
+ FALSE;
+
+ Success = SetFriendlyName(DeviceInfoSet,
+ DeviceInfoData,
+ (WORD)DeviceId,
+ Active);
+ if (!Success)
+ goto fail5;
+
+ if (!Active)
+ goto done;
+
Success = InstallFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
if (!Success)
- goto fail2;
+ goto fail6;
Success = InstallFilter(&GUID_HDC_DEVICE, "XENFILT");
if (!Success)
- goto fail3;
+ goto fail7;
Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
if (!Success)
- goto fail4;
+ goto fail8;
+
+done:
+ if (ActiveDeviceInstance != NULL)
+ free(ActiveDeviceInstance);
+
+ free(DeviceInstance);
Log("<====");
return NO_ERROR;
+fail8:
+ Log("fail8");
+
+ (VOID) RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
+
+fail7:
+ Log("fail7");
+
+ (VOID) RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
+
+fail6:
+ Log("fail6");
+
+fail5:
+ Log("fail5");
+
fail4:
Log("fail4");
+ if (ActiveDeviceInstance != NULL)
+ free(ActiveDeviceInstance);
+
fail3:
Log("fail3");
+ free(DeviceInstance);
+
fail2:
Log("fail2");
IN PCOINSTALLER_CONTEXT_DATA Context
)
{
- UNREFERENCED_PARAMETER(DeviceInfoSet);
- UNREFERENCED_PARAMETER(DeviceInfoData);
+ BOOLEAN Success;
+ PTCHAR DeviceInstance;
+ PTCHAR ActiveDeviceInstance;
+ BOOLEAN Active;
+ HRESULT Error;
+
UNREFERENCED_PARAMETER(Context);
- Log("<===>");
+ Log("====>");
+
+ DeviceInstance = GetDeviceInstance(DeviceInfoSet, DeviceInfoData);
+ if (DeviceInstance == NULL)
+ goto fail3;
+
+ Success = GetActiveDeviceInstance(&ActiveDeviceInstance);
+ if (!Success)
+ goto fail4;
+
+ Active = (ActiveDeviceInstance != NULL &&
+ strcmp(DeviceInstance, ActiveDeviceInstance) == 0) ?
+ TRUE :
+ FALSE;
+
+ if (!Active)
+ goto done;
+
+ ClearActiveDeviceInstance();
+
+ Success = RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
+ if (!Success)
+ goto fail1;
+
+ Success = RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
+ if (!Success)
+ goto fail2;
+
+ Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
+ if (!Success)
+ goto fail5;
+
+done:
+ if (ActiveDeviceInstance != NULL)
+ free(ActiveDeviceInstance);
+
+ free(DeviceInstance);
+
+ Log("<====");
return ERROR_DI_POSTPROCESSING_REQUIRED;
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ free(DeviceInstance);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
}
static FORCEINLINE HRESULT
)
{
HRESULT Error;
- BOOLEAN Success;
+
+ UNREFERENCED_PARAMETER(DeviceInfoSet);
+ UNREFERENCED_PARAMETER(DeviceInfoData);
+
+ Log("====>");
Error = Context->InstallResult;
if (Error != NO_ERROR) {
goto fail1;
}
- Success = RemoveFilter(&GUID_HDC_DEVICE, "XENFILT");
- if (!Success)
- goto fail2;
-
- Success = RemoveFilter(&GUID_SYSTEM_DEVICE, "XENFILT");
- if (!Success)
- goto fail3;
-
- Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
- if (!Success)
- goto fail4;
+ Log("<====");
return NO_ERROR;
-fail4:
-fail3:
-fail2:
fail1:
Error = GetLastError();
MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ if (!Context->PostProcessing) {
+ Log("%s PreProcessing",
+ FunctionName(Function));
+ } else {
+ Log("%s PostProcessing (%08x)",
+ FunctionName(Function),
+ Context->InstallResult);
+ }
+
switch (Function) {
case DIF_INSTALLDEVICE: {
SP_DRVINFO_DATA DriverInfoData;
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;
}
--- /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 _COMMON_ASSERT_H
+#define _COMMON_ASSERT_H
+
+#include <ntddk.h>
+
+#include "dbg_print.h"
+
+static FORCEINLINE VOID
+__Bug(
+ 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"); \
+ __Bug(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); \
+ __analysis_assume(_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 // _COMMON_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 _COMMON_DBG_PRINT_H
+#define _COMMON_DBG_PRINT_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__)
+
+#define DBG_PRINT_ENABLE_FILTER(_Id, _Level) \
+ do { \
+ DbgSetDebugFilterState((_Id), (_Level), TRUE); \
+ } while (FALSE)
+
+static __inline VOID
+__DbgPrintEnable(
+ VOID
+ )
+{
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL);
+
+#if DBG
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_WARNING_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL);
+ DBG_PRINT_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL);
+#endif // DBG
+}
+
+#endif // _COMMON_DBG_PRINT_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 _COMMON_HIGH_H
+#define _COMMON_HIGH_H
+
+#include <ntddk.h>
+
+#pragma warning(disable:4127) // conditional expression is constant
+
+typedef LONG HIGH_LOCK, *PHIGH_LOCK;
+
+#define LOCK_MAGIC 0xFEEDFACE
+
+static FORCEINLINE
+__drv_maxIRQL(HIGH_LEVEL)
+__drv_raisesIRQL(HIGH_LEVEL)
+__drv_savesIRQL
+KIRQL
+__AcquireHighLock(
+ IN PHIGH_LOCK Lock
+ )
+{
+ KIRQL Irql;
+
+ KeRaiseIrql(HIGH_LEVEL, &Irql);
+
+ while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
+ _mm_pause();
+
+ KeMemoryBarrier();
+
+ return Irql;
+}
+
+#define AcquireHighLock(_Lock, _Irql) \
+ do { \
+ *(_Irql) = __AcquireHighLock(_Lock); \
+ } while (FALSE)
+
+static FORCEINLINE
+__drv_maxIRQL(HIGH_LEVEL)
+__drv_requiresIRQL(HIGH_LEVEL)
+VOID
+ReleaseHighLock(
+ IN PHIGH_LOCK Lock,
+ IN __drv_restoresIRQL KIRQL Irql
+ )
+{
+ KeMemoryBarrier();
+
+ InterlockedExchange(Lock, 0);
+ KeLowerIrql(Irql);
+}
+
+static FORCEINLINE
+VOID
+InitializeHighLock(
+ IN PHIGH_LOCK Lock
+ )
+{
+ RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
+}
+
+#endif // _COMMON_HIGH_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 _COMMON_MUTEX_H
+#define _COMMON_MUTEX_H
+
+#include <ntddk.h>
+
+#include "assert.h"
+
+typedef struct _MUTEX {
+ PKTHREAD Owner;
+ KEVENT Event;
+} MUTEX, *PMUTEX;
+
+static FORCEINLINE VOID
+InitializeMutex(
+ IN PMUTEX Mutex
+ )
+{
+ RtlZeroMemory(Mutex, sizeof (MUTEX));
+
+ KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
+}
+
+static FORCEINLINE VOID
+__drv_maxIRQL(PASSIVE_LEVEL)
+AcquireMutex(
+ IN PMUTEX Mutex
+ )
+{
+ (VOID) KeWaitForSingleObject(&Mutex->Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ ASSERT3P(Mutex->Owner, ==, NULL);
+ Mutex->Owner = KeGetCurrentThread();
+}
+
+static FORCEINLINE VOID
+__drv_maxIRQL(PASSIVE_LEVEL)
+ReleaseMutex(
+ IN PMUTEX Mutex
+ )
+{
+ ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
+ Mutex->Owner = NULL;
+
+ KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
+}
+
+#endif // _COMMON_MUTEX_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 _COMMON_NAMES_H_
+#define _COMMON_NAMES_H_
+
+#include <ntddk.h>
+
+static FORCEINLINE const CHAR *
+PowerTypeName(
+ IN POWER_STATE_TYPE Type
+ )
+{
+#define _POWER_TYPE_NAME(_Type) \
+ case _Type: \
+ return #_Type;
+
+ switch (Type) {
+ _POWER_TYPE_NAME(SystemPowerState);
+ _POWER_TYPE_NAME(DevicePowerState);
+ default:
+ break;
+ }
+
+ return ("UNKNOWN");
+#undef _POWER_ACTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerSystemStateName(
+ IN SYSTEM_POWER_STATE State
+ )
+{
+#define _POWER_SYSTEM_STATE_NAME(_State) \
+ case PowerSystem ## _State: \
+ return #_State;
+
+ switch (State) {
+ _POWER_SYSTEM_STATE_NAME(Unspecified);
+ _POWER_SYSTEM_STATE_NAME(Working);
+ _POWER_SYSTEM_STATE_NAME(Sleeping1);
+ _POWER_SYSTEM_STATE_NAME(Sleeping2);
+ _POWER_SYSTEM_STATE_NAME(Sleeping3);
+ _POWER_SYSTEM_STATE_NAME(Hibernate);
+ _POWER_SYSTEM_STATE_NAME(Shutdown);
+ _POWER_SYSTEM_STATE_NAME(Maximum);
+ default:
+ break;
+ }
+
+ return ("UNKNOWN");
+#undef _POWER_SYSTEM_STATE_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerDeviceStateName(
+ IN DEVICE_POWER_STATE State
+ )
+{
+#define _POWER_DEVICE_STATE_NAME(_State) \
+ case PowerDevice ## _State: \
+ return #_State;
+
+ switch (State) {
+ _POWER_DEVICE_STATE_NAME(Unspecified);
+ _POWER_DEVICE_STATE_NAME(D0);
+ _POWER_DEVICE_STATE_NAME(D1);
+ _POWER_DEVICE_STATE_NAME(D2);
+ _POWER_DEVICE_STATE_NAME(D3);
+ _POWER_DEVICE_STATE_NAME(Maximum);
+ default:
+ break;
+ }
+
+ return ("UNKNOWN");
+#undef _POWER_DEVICE_STATE_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerActionName(
+ IN POWER_ACTION Type
+ )
+{
+#define _POWER_ACTION_NAME(_Type) \
+ case PowerAction ## _Type: \
+ return #_Type;
+
+ switch (Type) {
+ _POWER_ACTION_NAME(None);
+ _POWER_ACTION_NAME(Reserved);
+ _POWER_ACTION_NAME(Sleep);
+ _POWER_ACTION_NAME(Hibernate);
+ _POWER_ACTION_NAME(Shutdown);
+ _POWER_ACTION_NAME(ShutdownReset);
+ _POWER_ACTION_NAME(ShutdownOff);
+ _POWER_ACTION_NAME(WarmEject);
+ default:
+ break;
+ }
+
+ return ("UNKNOWN");
+#undef _POWER_ACTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PowerMinorFunctionName(
+ IN ULONG MinorFunction
+ )
+{
+#define _POWER_MINOR_FUNCTION_NAME(_Function) \
+ case IRP_MN_ ## _Function: \
+ return #_Function;
+
+ switch (MinorFunction) {
+ _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
+ _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
+ _POWER_MINOR_FUNCTION_NAME(SET_POWER);
+ _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
+
+ default:
+ return "UNKNOWN";
+ }
+
+#undef _POWER_MINOR_FUNCTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PnpMinorFunctionName(
+ IN ULONG Function
+ )
+{
+#define _PNP_MINOR_FUNCTION_NAME(_Function) \
+ case IRP_MN_ ## _Function: \
+ return #_Function;
+
+ switch (Function) {
+ _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
+ _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
+ _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
+ _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
+ _PNP_MINOR_FUNCTION_NAME(EJECT);
+ _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
+ _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
+ _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
+ _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _PNP_MINOR_FUNCTION_NAME
+}
+
+static FORCEINLINE const CHAR *
+PartialResourceDescriptorTypeName(
+ IN UCHAR Type
+ )
+{
+#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type) \
+ case CmResourceType ## _Type: \
+ return #_Type;
+
+ switch (Type) {
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
+ _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#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
+}
+
+#endif // _COMMON_NAMES_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 <util.h>
+
+#include "registry.h"
+#include "assert.h"
+
+#define REGISTRY_POOL 'GERX'
+
+static UNICODE_STRING RegistryPath;
+
+static FORCEINLINE PVOID
+__RegistryAllocate(
+ IN ULONG Length
+ )
+{
+ return __AllocateNonPagedPoolWithTag(Length, REGISTRY_POOL);
+}
+
+static FORCEINLINE VOID
+__RegistryFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, REGISTRY_POOL);
+}
+
+NTSTATUS
+RegistryInitialize(
+ IN PUNICODE_STRING Path
+ )
+{
+ NTSTATUS status;
+
+ ASSERT3P(RegistryPath.Buffer, ==, NULL);
+
+ status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+VOID
+RegistryTeardown(
+ VOID
+ )
+{
+ RtlFreeUnicodeString(&RegistryPath);
+ RegistryPath.Buffer = NULL;
+ RegistryPath.MaximumLength = RegistryPath.Length = 0;
+}
+
+NTSTATUS
+RegistryOpenServiceKey(
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ )
+{
+ OBJECT_ATTRIBUTES Attributes;
+ NTSTATUS status;
+
+ InitializeObjectAttributes(&Attributes,
+ &RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ status = ZwOpenKey(Key,
+ DesiredAccess,
+ &Attributes);
+ if (!NT_SUCCESS(status))
+ 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,
+ Key,
+ NULL);
+
+ status = ZwOpenKey(SubKey,
+ DesiredAccess,
+ &Attributes);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryCreateSubKey(
+ IN PHANDLE Key,
+ IN PCHAR Name
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ OBJECT_ATTRIBUTES Attributes;
+ HANDLE SubKey;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ InitializeObjectAttributes(&Attributes,
+ &Unicode,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ Key,
+ NULL);
+
+ status = ZwCreateKey(&SubKey,
+ KEY_ALL_ACCESS,
+ &Attributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ NULL
+ );
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ ZwClose(SubKey);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryDeleteSubKey(
+ IN PHANDLE Key,
+ IN PCHAR Name
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ OBJECT_ATTRIBUTES Attributes;
+ HANDLE SubKey;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ InitializeObjectAttributes(&Attributes,
+ &Unicode,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ Key,
+ NULL);
+
+ status = ZwOpenKey(&SubKey,
+ KEY_ALL_ACCESS,
+ &Attributes);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = ZwDeleteKey(SubKey);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ ZwClose(SubKey);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail3:
+ ZwClose(SubKey);
+
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryEnumerateSubKeys(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
+ )
+{
+ ULONG Size;
+ NTSTATUS status;
+ PKEY_FULL_INFORMATION Full;
+ PKEY_BASIC_INFORMATION Basic;
+ ULONG Index;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail1;
+
+ Full = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Full == NULL)
+ goto fail2;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ Full,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
+ Full->MaxNameLen;
+
+ Basic = __RegistryAllocate(Size);
+ status = STATUS_NO_MEMORY;
+ if (Basic == NULL)
+ goto fail4;
+
+ for (Index = 0; Index < Full->SubKeys; Index++) {
+ UNICODE_STRING Unicode;
+ ANSI_STRING Ansi;
+
+ status = ZwEnumerateKey(Key,
+ Index,
+ KeyBasicInformation,
+ Basic,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ Unicode.MaximumLength = (USHORT)Basic->NameLength;
+ Unicode.Buffer = Basic->Name;
+ Unicode.Length = (USHORT)Basic->NameLength;
+
+ Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+ Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+ status = 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
+RegistryEnumerateValues(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
+ )
+{
+ ULONG Size;
+ NTSTATUS status;
+ PKEY_FULL_INFORMATION Full;
+ PKEY_VALUE_BASIC_INFORMATION Basic;
+ ULONG Index;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail1;
+
+ Full = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Full == NULL)
+ goto fail2;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ Full,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
+ Full->MaxValueNameLen;
+
+ Basic = __RegistryAllocate(Size);
+ status = STATUS_NO_MEMORY;
+ if (Basic == NULL)
+ goto fail4;
+
+ for (Index = 0; Index < Full->Values; Index++) {
+ UNICODE_STRING Unicode;
+ ANSI_STRING Ansi;
+
+ status = ZwEnumerateValueKey(Key,
+ Index,
+ KeyValueBasicInformation,
+ Basic,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ Unicode.MaximumLength = (USHORT)Basic->NameLength;
+ Unicode.Buffer = Basic->Name;
+ Unicode.Length = (USHORT)Basic->NameLength;
+
+ Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+ Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+ status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+ ASSERT(NT_SUCCESS(status));
+
+ Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
+
+ status = Callback(Context, Key, Ansi.Buffer);
+
+ __RegistryFree(Ansi.Buffer);
+
+ if (!NT_SUCCESS(status))
+ goto fail6;
+ }
+
+ __RegistryFree(Basic);
+
+ __RegistryFree(Full);
+
+ return STATUS_SUCCESS;
+
+fail6:
+fail5:
+ __RegistryFree(Basic);
+
+fail4:
+fail3:
+ __RegistryFree(Full);
+
+fail2:
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryQueryDwordValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ OUT PULONG Value
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ ULONG Size;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail2;
+
+ Partial = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Partial == NULL)
+ goto fail3;
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ Partial,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Partial->Type != REG_DWORD ||
+ Partial->DataLength != sizeof (ULONG))
+ goto fail5;
+
+ *Value = *(PULONG)Partial->Data;
+
+ __RegistryFree(Partial);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail5:
+fail4:
+ __RegistryFree(Partial);
+
+fail3:
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryUpdateDwordValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ IN ULONG Value
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+ sizeof (ULONG));
+
+ status = STATUS_NO_MEMORY;
+ if (Partial == NULL)
+ goto fail2;
+
+ Partial->TitleIndex = 0;
+ Partial->Type = REG_DWORD;
+ Partial->DataLength = sizeof (ULONG);
+ *(PULONG)Partial->Data = Value;
+
+ status = ZwSetValueKey(Key,
+ &Unicode,
+ Partial->TitleIndex,
+ Partial->Type,
+ Partial->Data,
+ Partial->DataLength);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ __RegistryFree(Partial);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail3:
+ __RegistryFree(Partial);
+
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+
+ return status;
+}
+
+static PANSI_STRING
+RegistrySzToAnsi(
+ IN PWCHAR Buffer
+ )
+{
+ PANSI_STRING Ansi;
+ ULONG Length;
+ UNICODE_STRING Unicode;
+ NTSTATUS status;
+
+ Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi == NULL)
+ goto fail1;
+
+ Length = (ULONG)wcslen(Buffer);
+ Ansi[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
+ Ansi[0].Buffer = __RegistryAllocate(Ansi[0].MaximumLength);
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi[0].Buffer == NULL)
+ goto fail2;
+
+ RtlInitUnicodeString(&Unicode, Buffer);
+ status = RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
+ ASSERT(NT_SUCCESS(status));
+
+ Ansi[0].Length = (USHORT)Length * sizeof (CHAR);
+
+ return Ansi;
+
+fail2:
+ __RegistryFree(Ansi);
+
+fail1:
+ return NULL;
+}
+
+static PANSI_STRING
+RegistryMultiSzToAnsi(
+ IN PWCHAR Buffer
+ )
+{
+ PANSI_STRING Ansi;
+ LONG Index;
+ LONG Count;
+ NTSTATUS status;
+
+ Index = 0;
+ Count = 0;
+ for (;;) {
+ ULONG Length;
+
+ Length = (ULONG)wcslen(&Buffer[Index]);
+ if (Length == 0)
+ break;
+
+ Index += Length + 1;
+ Count++;
+ }
+
+ Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi == NULL)
+ goto fail1;
+
+ for (Index = 0; Index < Count; Index++) {
+ ULONG Length;
+ UNICODE_STRING Unicode;
+
+ Length = (ULONG)wcslen(Buffer);
+ Ansi[Index].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
+ Ansi[Index].Buffer = __RegistryAllocate(Ansi[Index].MaximumLength);
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi[Index].Buffer == NULL)
+ goto fail2;
+
+ RtlInitUnicodeString(&Unicode, Buffer);
+
+ status = RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FALSE);
+ ASSERT(NT_SUCCESS(status));
+
+ Ansi[Index].Length = (USHORT)Length * sizeof (CHAR);
+ Buffer += Length + 1;
+ }
+
+ return Ansi;
+
+fail2:
+ while (--Index >= 0)
+ __RegistryFree(Ansi[Index].Buffer);
+
+ __RegistryFree(Ansi);
+
+fail1:
+ return NULL;
+}
+
+NTSTATUS
+RegistryQuerySzValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ OUT PANSI_STRING *Array
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ PKEY_VALUE_PARTIAL_INFORMATION Value;
+ ULONG Size;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail2;
+
+ Value = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Value == NULL)
+ goto fail3;
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ Value,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ switch (Value->Type) {
+ case REG_SZ:
+ status = STATUS_NO_MEMORY;
+ *Array = RegistrySzToAnsi((PWCHAR)Value->Data);
+ break;
+
+ case REG_MULTI_SZ:
+ status = STATUS_NO_MEMORY;
+ *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data);
+ break;
+
+ default:
+ status = STATUS_INVALID_PARAMETER;
+ *Array = NULL;
+ break;
+ }
+
+ if (*Array == NULL)
+ goto fail5;
+
+ __RegistryFree(Value);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail5:
+fail4:
+ __RegistryFree(Value);
+
+fail3:
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+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
+ )
+{
+ ULONG Length;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ UNICODE_STRING Unicode;
+ NTSTATUS status;
+
+ Length = Ansi->Length + 1;
+ Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+ Length * sizeof (WCHAR));
+
+ status = STATUS_NO_MEMORY;
+ if (Partial == NULL)
+ goto fail1;
+
+ Partial->TitleIndex = 0;
+ Partial->Type = REG_SZ;
+ Partial->DataLength = Length * sizeof (WCHAR);
+
+ Unicode.MaximumLength = (UCHAR)Partial->DataLength;
+ Unicode.Buffer = (PWCHAR)Partial->Data;
+ Unicode.Length = 0;
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ return Partial;
+
+fail2:
+ __RegistryFree(Partial);
+
+fail1:
+ return NULL;
+}
+
+static PKEY_VALUE_PARTIAL_INFORMATION
+RegistryAnsiToMultiSz(
+ PANSI_STRING Ansi
+ )
+{
+ ULONG Length;
+ ULONG Index;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ UNICODE_STRING Unicode;
+ NTSTATUS status;
+
+ Length = 1;
+ for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+ Length += Ansi[Index].Length + 1;
+
+ Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+ Length * sizeof (WCHAR));
+
+ status = STATUS_NO_MEMORY;
+ if (Partial == NULL)
+ goto fail1;
+
+ Partial->TitleIndex = 0;
+ Partial->Type = REG_MULTI_SZ;
+ Partial->DataLength = Length * sizeof (WCHAR);
+
+ Unicode.MaximumLength = (USHORT)Partial->DataLength;
+ Unicode.Buffer = (PWCHAR)Partial->Data;
+ Unicode.Length = 0;
+
+ for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ Length = Unicode.Length / sizeof (WCHAR);
+
+ ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
+ Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
+ Unicode.Buffer += Length + 1;
+ Unicode.Length = 0;
+ }
+ *Unicode.Buffer = L'\0';
+
+ return Partial;
+
+fail2:
+ __RegistryFree(Partial);
+
+fail1:
+ return NULL;
+}
+
+NTSTATUS
+RegistryUpdateSzValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ IN ULONG Type,
+ ...
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ va_list Arguments;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ va_start(Arguments, Type);
+ switch (Type) {
+ case REG_SZ: {
+ PANSI_STRING Argument;
+
+ Argument = va_arg(Arguments, PANSI_STRING);
+
+ status = STATUS_NO_MEMORY;
+ Partial = RegistryAnsiToSz(Argument);
+ break;
+ }
+ case REG_MULTI_SZ: {
+ PANSI_STRING Argument;
+
+ Argument = va_arg(Arguments, PANSI_STRING);
+
+ status = STATUS_NO_MEMORY;
+ Partial = RegistryAnsiToMultiSz(Argument);
+ break;
+ }
+ default:
+ status = STATUS_INVALID_PARAMETER;
+ Partial = NULL;
+ break;
+ }
+ va_end(Arguments);
+
+ if (Partial == NULL)
+ goto fail2;
+
+ status = ZwSetValueKey(Key,
+ &Unicode,
+ Partial->TitleIndex,
+ Partial->Type,
+ Partial->Data,
+ Partial->DataLength);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ __RegistryFree(Partial);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ return STATUS_SUCCESS;
+
+fail3:
+ __RegistryFree(Partial);
+
+fail2:
+ RtlFreeUnicodeString(&Unicode);
+
+fail1:
+ return status;
+}
+
+VOID
+RegistryFreeSzValue(
+ IN PANSI_STRING Array
+ )
+{
+ ULONG Index;
+
+ if (Array == NULL)
+ return;
+
+ for (Index = 0; Array[Index].Buffer != NULL; Index++)
+ __RegistryFree(Array[Index].Buffer);
+
+ __RegistryFree(Array);
+}
+
+VOID
+RegistryCloseKey(
+ IN HANDLE Key
+ )
+{
+ ZwClose(Key);
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COMMON_REGISTRY_H
+#define _COMMON_REGISTRY_H
+
+#include <ntddk.h>
+
+extern NTSTATUS
+RegistryInitialize(
+ IN PUNICODE_STRING Path
+ );
+
+extern VOID
+RegistryTeardown(
+ 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 SubKey
+ );
+
+extern NTSTATUS
+RegistryCreateSubKey(
+ IN HANDLE Key,
+ IN PCHAR Name
+ );
+
+extern NTSTATUS
+RegistryDeleteSubKey(
+ IN HANDLE Key,
+ IN PCHAR Name
+ );
+
+extern NTSTATUS
+RegistryEnumerateSubKeys(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
+ );
+
+extern NTSTATUS
+RegistryEnumerateValues(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
+ );
+
+extern NTSTATUS
+RegistryQueryDwordValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ OUT PULONG Value
+ );
+
+extern NTSTATUS
+RegistryUpdateDwordValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ IN ULONG Value
+ );
+
+extern NTSTATUS
+RegistryQuerySzValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ OUT PANSI_STRING *Array
+ );
+
+extern NTSTATUS
+RegistryQuerySystemStartOption(
+ IN PCHAR Name,
+ OUT PANSI_STRING *Option
+ );
+
+extern VOID
+RegistryFreeSzValue(
+ IN PANSI_STRING Array
+ );
+
+extern NTSTATUS
+RegistryUpdateSzValue(
+ IN HANDLE Key,
+ IN PCHAR Name,
+ IN ULONG Type,
+ ...
+ );
+
+extern VOID
+RegistryCloseKey(
+ IN HANDLE Key
+ );
+
+#endif // _COMMON_REGISTRY_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 _COMMON_UTIL_H
+#define _COMMON_UTIL_H
+
+#include <ntddk.h>
+
+#include "assert.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 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,
+ 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;
+}
+
+typedef struct _NON_PAGED_BUFFER_HEADER {
+ SIZE_T Length;
+ ULONG Tag;
+} NON_PAGED_BUFFER_HEADER, *PNON_PAGED_BUFFER_HEADER;
+
+typedef struct _NON_PAGED_BUFFER_TRAILER {
+ ULONG Tag;
+} NON_PAGED_BUFFER_TRAILER, *PNON_PAGED_BUFFER_TRAILER;
+
+static FORCEINLINE PVOID
+__AllocateNonPagedPoolWithTag(
+ IN SIZE_T Length,
+ IN ULONG Tag
+ )
+{
+ PUCHAR Buffer;
+ PNON_PAGED_BUFFER_HEADER Header;
+ PNON_PAGED_BUFFER_TRAILER Trailer;
+
+ ASSERT(Length != 0);
+
+ Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof (NON_PAGED_BUFFER_HEADER) +
+ Length +
+ sizeof (NON_PAGED_BUFFER_TRAILER),
+ Tag);
+ if (Buffer == NULL)
+ goto done;
+
+ RtlZeroMemory(Buffer,
+ sizeof (NON_PAGED_BUFFER_HEADER) +
+ Length +
+ sizeof (NON_PAGED_BUFFER_TRAILER));
+
+ Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+ Header->Length = Length;
+ Header->Tag = Tag;
+
+ Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+ Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+ Trailer->Tag = Tag;
+
+done:
+ return Buffer;
+}
+
+static FORCEINLINE VOID
+__FreePoolWithTag(
+ IN PVOID _Buffer,
+ IN ULONG Tag
+ )
+{
+ PUCHAR Buffer = _Buffer;
+ SIZE_T Length;
+ PNON_PAGED_BUFFER_HEADER Header;
+ PNON_PAGED_BUFFER_TRAILER Trailer;
+
+ ASSERT(Buffer != NULL);
+
+ Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+ Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+ ASSERT3U(Tag, ==, Header->Tag);
+ Length = Header->Length;
+
+ Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+ Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+ ASSERT3U(Tag, ==, Trailer->Tag);
+
+ Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+ RtlFillMemory(Buffer,
+ sizeof (NON_PAGED_BUFFER_HEADER) +
+ Length +
+ sizeof (NON_PAGED_BUFFER_TRAILER),
+ 0xAA);
+
+ ExFreePoolWithTag(Buffer, Tag);
+}
+
+static FORCEINLINE PMDL
+__AllocatePage(
+ VOID
+ )
+{
+ PHYSICAL_ADDRESS LowAddress;
+ PHYSICAL_ADDRESS HighAddress;
+ LARGE_INTEGER SkipBytes;
+ SIZE_T TotalBytes;
+ PMDL Mdl;
+ PUCHAR MdlMappedSystemVa;
+ NTSTATUS status;
+
+ LowAddress.QuadPart = 0ull;
+ HighAddress.QuadPart = ~0ull;
+ SkipBytes.QuadPart = 0ull;
+ TotalBytes = (SIZE_T)PAGE_SIZE;
+
+ Mdl = MmAllocatePagesForMdlEx(LowAddress,
+ HighAddress,
+ SkipBytes,
+ TotalBytes,
+ MmCached,
+ 0);
+
+ status = STATUS_NO_MEMORY;
+ if (Mdl == NULL)
+ goto fail1;
+
+ ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
+ MDL_PARTIAL_HAS_BEEN_MAPPED |
+ MDL_PARTIAL |
+ MDL_PARENT_MAPPED_SYSTEM_VA |
+ MDL_SOURCE_IS_NONPAGED_POOL |
+ MDL_IO_SPACE)) == 0);
+
+ MdlMappedSystemVa = MmMapLockedPagesSpecifyCache(Mdl,
+ KernelMode,
+ MmCached,
+ NULL,
+ FALSE,
+ NormalPagePriority);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (MdlMappedSystemVa == NULL)
+ goto fail2;
+
+ ASSERT3P(MdlMappedSystemVa, ==, Mdl->MappedSystemVa);
+
+ RtlZeroMemory(MdlMappedSystemVa, PAGE_SIZE);
+
+ return Mdl;
+
+fail2:
+ Error("fail2\n");
+
+ MmFreePagesFromMdl(Mdl);
+ ExFreePool(Mdl);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return NULL;
+}
+
+static FORCEINLINE VOID
+__FreePage(
+ IN PMDL Mdl
+ )
+{
+ PUCHAR MdlMappedSystemVa;
+
+ ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
+ MdlMappedSystemVa = Mdl->MappedSystemVa;
+
+ RtlFillMemory(MdlMappedSystemVa, PAGE_SIZE, 0xAA);
+
+ MmUnmapLockedPages(MdlMappedSystemVa, Mdl);
+
+ MmFreePagesFromMdl(Mdl);
+}
+
+static FORCEINLINE 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 // _COMMON_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 _XEN_ASSERT_H
-#define _XEN_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); \
- __analysis_assume(_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 // _XEN_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.
+ */
+
+#define XEN_API extern
+
+#include <ntddk.h>
+#include <xen.h>
+#include <bugcodes.h>
+
+#include "hypercall.h"
+#include "module.h"
+#include "log.h"
+#include "bug_check.h"
+#include "dbg_print.h"
+#include "assert.h"
+
+static KBUGCHECK_CALLBACK_RECORD BugCheckBugCheckCallbackRecord;
+
+VOID
+BugCheckTeardown(
+ VOID
+ )
+{
+ (VOID) KeDeregisterBugCheckCallback(&BugCheckBugCheckCallbackRecord);
+}
+
+#pragma warning(push)
+#pragma warning(disable: 6320) // Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled.
+#pragma warning(disable: 6322) // Empty _except block.
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpExceptionRecord(
+ IN PEXCEPTION_RECORD Exception
+ )
+{
+ __try {
+ while (Exception != NULL) {
+ ULONG Index;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: EXCEPTION (%p):\n",
+ __MODULE__,
+ Exception);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - Code = %08X\n",
+ __MODULE__,
+ Exception->ExceptionCode);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - Flags = %08X\n",
+ __MODULE__,
+ Exception->ExceptionFlags);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - Address = %p\n",
+ __MODULE__,
+ Exception->ExceptionAddress);
+
+ for (Index = 0; Index < Exception->NumberParameters; Index++)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - Parameter[%u] = %p\n", __MODULE__,
+ Index,
+ (PVOID)Exception->ExceptionInformation[Index]);
+
+ Exception = Exception->ExceptionRecord;
+ }
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Nothing to to
+ }
+}
+
+#pragma warning(push)
+#pragma warning(disable:6262) // Uses more than 1024 bytes of stack
+
+#if defined(__i386__)
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpContext(
+ IN PCONTEXT Context
+ )
+{
+ __try {
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: CONTEXT (%p):\n",
+ __MODULE__,
+ Context);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - GS = %04X\n",
+ __MODULE__,
+ Context->SegGs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - FS = %04X\n",
+ __MODULE__,
+ Context->SegFs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - ES = %08X\n",
+ __MODULE__,
+ Context->SegEs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - DS = %08X\n",
+ __MODULE__,
+ Context->SegDs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - SS = %08X\n",
+ __MODULE__,
+ Context->SegSs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - CS = %08X\n",
+ __MODULE__,
+ Context->SegCs);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EFLAGS = %08X\n",
+ __MODULE__,
+ Context->EFlags);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EDI = %08X\n",
+ __MODULE__,
+ Context->Edi);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - ESI = %08X\n",
+ __MODULE__,
+ Context->Esi);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EBX = %08X\n",
+ __MODULE__,
+ Context->Ebx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EDX = %08X\n",
+ __MODULE__,
+ Context->Edx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - ECX = %08X\n",
+ __MODULE__,
+ Context->Ecx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EAX = %08X\n",
+ __MODULE__,
+ Context->Eax);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EBP = %08X\n",
+ __MODULE__,
+ Context->Ebp);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EIP = %08X\n",
+ __MODULE__,
+ Context->Eip);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - ESP = %08X\n",
+ __MODULE__,
+ Context->Esp);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Nothing to to
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckStackDump(
+ IN PCONTEXT Context
+ )
+{
+#define PARAMETER_COUNT 3
+#define MAXIMUM_ITERATIONS 20
+
+ __try {
+ ULONG_PTR EBP;
+ ULONG Iteration;
+
+ BugCheckDumpContext(Context);
+
+ EBP = (ULONG_PTR)Context->Ebp;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: STACK:\n",
+ __MODULE__);
+
+ for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
+ ULONG NextEBP;
+ ULONG EIP;
+ ULONG Parameter[PARAMETER_COUNT] = {0};
+ ULONG Index;
+ PCHAR Name;
+ ULONG Offset;
+
+ NextEBP = *(PULONG)EBP;
+ EIP = *(PULONG)(EBP + 4);
+
+ if (EIP == 0)
+ break;
+
+ Index = 0;
+ Offset = 8;
+ for (;;) {
+ if (EBP + Offset >= NextEBP)
+ break;
+
+ if (Index == PARAMETER_COUNT)
+ break;
+
+ Parameter[Index] = *(PULONG)(EBP + Offset);
+
+ Index += 1;
+ Offset += 4;
+ }
+
+ ModuleLookup(EIP, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X: (%08X %08X %08X) %s + %p\n", __MODULE__,
+ EBP,
+ Parameter[0],
+ Parameter[1],
+ Parameter[2],
+ Name,
+ (PVOID)Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X: (%08X %08X %08X) %p\n", __MODULE__,
+ EBP,
+ Parameter[0],
+ Parameter[1],
+ Parameter[2],
+ (PVOID)EIP);
+
+ EBP = NextEBP;
+ }
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // End of stack
+ }
+
+#undef MAXIMUM_ITERATIONS
+#undef PARAMETER_COUNT
+}
+#elif defined(__x86_64__)
+static DECLSPEC_NOINLINE VOID
+BugCheckDumpContext(
+ IN PCONTEXT Context
+ )
+{
+ __try {
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: CONTEXT (%p):\n",
+ __MODULE__,
+ Context);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - GS = %04X\n",
+ __MODULE__,
+ Context->SegGs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - FS = %04X\n",
+ __MODULE__,
+ Context->SegFs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - ES = %04X\n",
+ __MODULE__,
+ Context->SegEs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - DS = %04X\n",
+ __MODULE__,
+ Context->SegDs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - SS = %04X\n",
+ __MODULE__,
+ Context->SegSs);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - CS = %04X\n",
+ __MODULE__,
+ Context->SegCs);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - EFLAGS = %08X\n",
+ __MODULE__,
+ Context->EFlags);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RDI = %016X\n",
+ __MODULE__,
+ Context->Rdi);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RSI = %016X\n",
+ __MODULE__,
+ Context->Rsi);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RBX = %016X\n",
+ __MODULE__,
+ Context->Rbx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RDX = %016X\n",
+ __MODULE__,
+ Context->Rdx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RCX = %016X\n",
+ __MODULE__,
+ Context->Rcx);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RAX = %016X\n",
+ __MODULE__,
+ Context->Rax);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RBP = %016X\n",
+ __MODULE__,
+ Context->Rbp);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RIP = %016X\n",
+ __MODULE__,
+ Context->Rip);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - RSP = %016X\n",
+ __MODULE__,
+ Context->Rsp);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R8 = %016X\n",
+ __MODULE__,
+ Context->R8);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R9 = %016X\n",
+ __MODULE__,
+ Context->R9);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R10 = %016X\n",
+ __MODULE__,
+ Context->R10);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R11 = %016X\n",
+ __MODULE__,
+ Context->R11);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R12 = %016X\n",
+ __MODULE__,
+ Context->R12);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R13 = %016X\n",
+ __MODULE__,
+ Context->R13);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R14 = %016X\n",
+ __MODULE__,
+ Context->R14);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - R15 = %016X\n",
+ __MODULE__,
+ Context->R15);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Nothing to to
+ }
+}
+
+typedef struct _RUNTIME_FUNCTION {
+ ULONG BeginAddress;
+ ULONG EndAddress;
+ ULONG UnwindData;
+} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
+
+#define UNWIND_HISTORY_TABLE_SIZE 12
+
+typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
+
+#define UNWIND_HISTORY_TABLE_NONE 0
+#define UNWIND_HISTORY_TABLE_GLOBAL 1
+#define UNWIND_HISTORY_TABLE_LOCAL 2
+
+typedef struct _UNWIND_HISTORY_TABLE {
+ ULONG Count;
+ UCHAR Search;
+ UCHAR RaiseStatusIndex;
+ BOOLEAN Unwind;
+ BOOLEAN Exception;
+ ULONG64 LowAddress;
+ ULONG64 HighAddress;
+ UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
+} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
+
+extern PRUNTIME_FUNCTION
+RtlLookupFunctionEntry(
+ __in ULONG64 ControlPc,
+ __out PULONG64 ImageBase,
+ __inout_opt PUNWIND_HISTORY_TABLE HistoryTable OPTIONAL
+ );
+
+#pragma prefast(suppress:28301) // No annotations
+typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
+ __in struct _EXCEPTION_RECORD *ExceptionRecord,
+ __in PVOID EstablisherFrame,
+ __inout struct _CONTEXT *ContextRecord,
+ __inout PVOID DispatcherContext
+ );
+
+#pragma warning(push)
+#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
+
+typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
+ union {
+ PM128A FloatingContext[16];
+ struct {
+ PM128A Xmm0;
+ PM128A Xmm1;
+ PM128A Xmm2;
+ PM128A Xmm3;
+ PM128A Xmm4;
+ PM128A Xmm5;
+ PM128A Xmm6;
+ PM128A Xmm7;
+ PM128A Xmm8;
+ PM128A Xmm9;
+ PM128A Xmm10;
+ PM128A Xmm11;
+ PM128A Xmm12;
+ PM128A Xmm13;
+ PM128A Xmm14;
+ PM128A Xmm15;
+ };
+ };
+
+ union {
+ PULONG64 IntegerContext[16];
+ struct {
+ PULONG64 Rax;
+ PULONG64 Rcx;
+ PULONG64 Rdx;
+ PULONG64 Rbx;
+ PULONG64 Rsp;
+ PULONG64 Rbp;
+ PULONG64 Rsi;
+ PULONG64 Rdi;
+ PULONG64 R8;
+ PULONG64 R9;
+ PULONG64 R10;
+ PULONG64 R11;
+ PULONG64 R12;
+ PULONG64 R13;
+ PULONG64 R14;
+ PULONG64 R15;
+ };
+ };
+} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+
+#pragma warning(pop)
+
+#define UNW_FLAG_NHANDLER 0
+#define UNW_FLAG_EHANDLER 1
+#define UNW_FLAG_UHANDLER 2
+
+extern PEXCEPTION_ROUTINE
+RtlVirtualUnwind(
+ __in ULONG HandlerType,
+ __in ULONG64 ImageBase,
+ __in ULONG64 ControlPc,
+ __in PRUNTIME_FUNCTION FunctionEntry,
+ __inout PCONTEXT ContextRecord,
+ __out PVOID *HandlerData,
+ __out PULONG64 EstablisherFrame,
+ __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
+ );
+
+static DECLSPEC_NOINLINE VOID
+BugCheckStackDump(
+ IN PCONTEXT Context
+ )
+{
+#define PARAMETER_COUNT 4
+#define MAXIMUM_ITERATIONS 20
+
+ __try {
+ ULONG Iteration;
+
+ BugCheckDumpContext(Context);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: STACK:\n",
+ __MODULE__);
+
+ for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
+ PRUNTIME_FUNCTION FunctionEntry;
+ ULONG64 ImageBase;
+ ULONG64 RIP;
+ ULONG64 RSP;
+ ULONG64 Parameter[PARAMETER_COUNT] = {0};
+ ULONG Index;
+ PCHAR Name;
+ ULONG64 Offset;
+
+ if (Context->Rip == 0)
+ break;
+
+ FunctionEntry = RtlLookupFunctionEntry(Context->Rip,
+ &ImageBase,
+ NULL);
+
+ if (FunctionEntry != NULL) {
+ CONTEXT UnwindContext;
+ ULONG64 ControlPc;
+ PVOID HandlerData;
+ ULONG64 EstablisherFrame;
+ KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
+
+ UnwindContext = *Context;
+ ControlPc = Context->Rip;
+ HandlerData = NULL;
+ EstablisherFrame = 0;
+ RtlZeroMemory(&ContextPointers, sizeof (KNONVOLATILE_CONTEXT_POINTERS));
+
+ (VOID) RtlVirtualUnwind(UNW_FLAG_UHANDLER,
+ ImageBase,
+ ControlPc,
+ FunctionEntry,
+ &UnwindContext,
+ &HandlerData,
+ &EstablisherFrame,
+ &ContextPointers);
+
+ *Context = UnwindContext;
+ } else {
+ Context->Rip = *(PULONG64)(Context->Rsp);
+ Context->Rsp += sizeof (ULONG64);
+ }
+
+ RSP = Context->Rsp;
+ RIP = Context->Rip;
+
+ Index = 0;
+ Offset = 0;
+ for (;;) {
+ if (Index == PARAMETER_COUNT)
+ break;
+
+ Parameter[Index] = *(PULONG64)(RSP + Offset);
+
+ Index += 1;
+ Offset += 8;
+ }
+
+ ModuleLookup(RIP, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %016X: (%016X %016X %016X %016X) %s + %p\n",
+ __MODULE__,
+ RSP,
+ Parameter[0],
+ Parameter[1],
+ Parameter[2],
+ Parameter[3],
+ Name,
+ (PVOID)Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %016X: (%016X %016X %016X %016X) %p\n",
+ __MODULE__,
+ RSP,
+ Parameter[0],
+ Parameter[1],
+ Parameter[2],
+ Parameter[3],
+ (PVOID)RIP);
+ }
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+#else
+#error 'Unrecognised architecture'
+#endif
+
+extern VOID
+RtlCaptureContext(
+ __out PCONTEXT Context
+ );
+
+static DECLSPEC_NOINLINE VOID
+BugCheckIrqlNotLessOrEqual(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ CONTEXT Context;
+ PVOID Memory = (PVOID)Parameter1;
+ KIRQL Irql = (KIRQL)Parameter2;
+ ULONG_PTR Access = Parameter3;
+ PVOID Address = (PVOID)Parameter4;
+ PCHAR Name;
+ ULONG_PTR Offset;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: MEMORY REFERENCED: %p\n",
+ __MODULE__,
+ Memory);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: IRQL: %02x\n",
+ __MODULE__,
+ Irql);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ACCESS: %p\n",
+ __MODULE__,
+ (PVOID)Access);
+
+ ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ADDRESS: %s + %p\n",
+ __MODULE__,
+ Name,
+ Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ADDRESS: %p\n",
+ __MODULE__,
+ Address);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDriverIrqlNotLessOrEqual(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ CONTEXT Context;
+ PVOID Memory = (PVOID)Parameter1;
+ KIRQL Irql = (KIRQL)Parameter2;
+ ULONG_PTR Access = Parameter3;
+ PVOID Address = (PVOID)Parameter4;
+ PCHAR Name;
+ ULONG_PTR Offset;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: MEMORY REFERENCED: %p\n",
+ __MODULE__,
+ Memory);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: IRQL: %02X\n",
+ __MODULE__,
+ Irql);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ACCESS: %p\n",
+ __MODULE__,
+ (PVOID)Access);
+
+ ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ADDRESS: %s + %p\n",
+ __MODULE__,
+ Name,
+ Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ADDRESS: %p\n",
+ __MODULE__,
+ Address);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckSystemServiceException(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ PEXCEPTION_RECORD Exception = (PEXCEPTION_RECORD)Parameter2;
+ PCONTEXT Context = (PCONTEXT)Parameter3;
+
+ UNREFERENCED_PARAMETER(Parameter1);
+ UNREFERENCED_PARAMETER(Parameter4);
+
+ BugCheckDumpExceptionRecord(Exception);
+
+ BugCheckStackDump(Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckSystemThreadExceptionNotHandled(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ ULONG Code = (ULONG)Parameter1;
+ PVOID Address = (PVOID)Parameter2;
+ PEXCEPTION_RECORD Exception = (PEXCEPTION_RECORD)Parameter3;
+ PCONTEXT Context = (PCONTEXT)Parameter4;
+ PCHAR Name;
+ ULONG_PTR Offset;
+
+ ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X AT %s + %p\n",
+ __MODULE__,
+ Code,
+ Name,
+ Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X AT %p\n",
+ __MODULE__,
+ Code,
+ Name,
+ Address);
+
+ BugCheckDumpExceptionRecord(Exception);
+
+ BugCheckStackDump(Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckKernelModeExceptionNotHandled(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ CONTEXT Context;
+ ULONG Code = (ULONG)Parameter1;
+ PVOID Address = (PVOID)Parameter2;
+ PCHAR Name;
+ ULONG_PTR Offset;
+
+ UNREFERENCED_PARAMETER(Parameter3);
+ UNREFERENCED_PARAMETER(Parameter4);
+
+ ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X AT %s + %p\n",
+ __MODULE__,
+ Code,
+ Name,
+ Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X AT %p\n",
+ __MODULE__,
+ Code,
+ Name,
+ Address);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: - Code = %08X\n",
+ __MODULE__,
+ Code);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckCriticalObjectTermination(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ ULONG Type = (ULONG)Parameter1;
+ PVOID Object = (PVOID)Parameter2;
+ PCHAR Name = (PCHAR)Parameter3;
+ PCHAR Reason = (PCHAR)Parameter4;
+ CONTEXT Context;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: Type = %08X\n",
+ __MODULE__,
+ Type);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: Object = %p\n",
+ __MODULE__,
+ Object);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: Name = %s\n",
+ __MODULE__,
+ Name);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: Reason = %s\n",
+ __MODULE__,
+ Reason);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckInaccessibleBootDevice(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ PUNICODE_STRING Unicode = (PUNICODE_STRING)Parameter1;
+ CONTEXT Context;
+
+ UNREFERENCED_PARAMETER(Parameter2);
+ UNREFERENCED_PARAMETER(Parameter3);
+ UNREFERENCED_PARAMETER(Parameter4);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %wZ\n",
+ __MODULE__,
+ Unicode);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDriverPowerStateFailure(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ ULONG_PTR Code = Parameter1;
+
+ UNREFERENCED_PARAMETER(Parameter3);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: Code %08x\n",
+ __MODULE__,
+ Code);
+
+ switch (Code) {
+ case 0x1: {
+ PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parameter2;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: OUTSTANDING IRP (Device Object %p)\n",
+ __MODULE__,
+ DeviceObject);
+
+ break;
+ }
+ case 0x3: {
+ PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parameter2;
+ PIRP Irp = (PIRP)Parameter4;
+ PIO_STACK_LOCATION StackLocation;
+ LONG Index;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: OUTSTANDING IRP %p (Device Object %p)\n",
+ __MODULE__,
+ Irp,
+ DeviceObject);
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: IRP STACK:\n",
+ __MODULE__);
+
+ for (Index = 0; Index <= Irp->StackCount; Index++) {
+ PCHAR Name;
+ ULONG_PTR Offset;
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: [%c%u] %02x %02x %02x %02x\n",
+ __MODULE__,
+ (Index == Irp->CurrentLocation) ? '>' : ' ',
+ Index,
+ StackLocation->MajorFunction,
+ StackLocation->MinorFunction,
+ StackLocation->Flags,
+ StackLocation->Control);
+
+ ModuleLookup((ULONG_PTR)StackLocation->CompletionRoutine, &Name, &Offset);
+
+ if (Name != NULL)
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: [%c%u] CompletionRoutine = %s + %p\n",
+ __MODULE__,
+ (Index == Irp->CurrentLocation) ? '>' : ' ',
+ Index,
+ Name,
+ (PVOID)Offset);
+ else
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: [%c%u] CompletionRoutine = %p\n",
+ __MODULE__,
+ (Index == Irp->CurrentLocation) ? '>' : ' ',
+ Index,
+ StackLocation->CompletionRoutine);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: [%c%u] Context = %p\n",
+ __MODULE__,
+ (Index == Irp->CurrentLocation) ? '>' : ' ',
+ Index,
+ StackLocation->Context);
+
+ StackLocation++;
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+static DECLSPEC_NOINLINE VOID
+BugCheckAssertionFailure(
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+ __try {
+ PCHAR Text = (PCHAR)Parameter1;
+ PCHAR File = (PCHAR)Parameter2;
+ ULONG Line = (ULONG)Parameter3;
+ CONTEXT Context;
+
+ UNREFERENCED_PARAMETER(Parameter4);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: FILE: %s LINE: %u\n", __MODULE__,
+ File,
+ Line);
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: TEXT: %s\n", __MODULE__,
+ Text);
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+struct _BUG_CODE_ENTRY {
+ ULONG Code;
+ const CHAR *Name;
+ VOID (*Handler)(ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR);
+};
+
+#define DEFINE_HANDLER(_Code, _Function) \
+ { (_Code), #_Code, (_Function) }
+
+struct _BUG_CODE_ENTRY BugCodeTable[] = {
+ DEFINE_HANDLER(IRQL_NOT_LESS_OR_EQUAL, BugCheckIrqlNotLessOrEqual),
+ DEFINE_HANDLER(DRIVER_IRQL_NOT_LESS_OR_EQUAL, BugCheckDriverIrqlNotLessOrEqual),
+ DEFINE_HANDLER(SYSTEM_SERVICE_EXCEPTION, BugCheckSystemServiceException),
+ DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED, BugCheckSystemThreadExceptionNotHandled),
+ DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M, BugCheckSystemThreadExceptionNotHandled),
+ DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED, BugCheckKernelModeExceptionNotHandled),
+ DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED_M, BugCheckKernelModeExceptionNotHandled),
+ DEFINE_HANDLER(CRITICAL_OBJECT_TERMINATION, BugCheckCriticalObjectTermination),
+ DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, BugCheckInaccessibleBootDevice),
+ DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, BugCheckDriverPowerStateFailure),
+ DEFINE_HANDLER(ASSERTION_FAILURE, BugCheckAssertionFailure),
+ { 0, NULL, NULL }
+};
+
+static DECLSPEC_NOINLINE VOID
+BugCheckDefaultHandler(
+ VOID
+ )
+{
+ __try {
+ CONTEXT Context;
+
+ RtlCaptureContext(&Context);
+ BugCheckStackDump(&Context);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ // Error of some kind
+ }
+}
+
+#pragma warning(pop)
+
+KBUGCHECK_CALLBACK_ROUTINE BugCheckBugCheckCallback;
+
+VOID
+BugCheckBugCheckCallback(
+ IN PVOID Argument,
+ IN ULONG Length
+ )
+{
+ extern PULONG_PTR KiBugCheckData;
+ ULONG Code;
+ ULONG_PTR Parameter1;
+ ULONG_PTR Parameter2;
+ ULONG_PTR Parameter3;
+ ULONG_PTR Parameter4;
+ struct _BUG_CODE_ENTRY *Entry;
+
+ UNREFERENCED_PARAMETER(Argument);
+ UNREFERENCED_PARAMETER(Length);
+
+ (VOID) SchedShutdownCode(SHUTDOWN_crash);
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: ====>\n",
+ __MODULE__);
+
+ Code = (ULONG)KiBugCheckData[0];
+ Parameter1 = KiBugCheckData[1];
+ Parameter2 = KiBugCheckData[2];
+ Parameter3 = KiBugCheckData[3];
+ Parameter4 = KiBugCheckData[4];
+
+ for (Entry = BugCodeTable; Entry->Code != 0; Entry++) {
+ if (Code == Entry->Code) {
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %s: %p %p %p %p\n",
+ __MODULE__,
+ Entry->Name,
+ (PVOID)Parameter1,
+ (PVOID)Parameter2,
+ (PVOID)Parameter3,
+ (PVOID)Parameter4);
+
+ Entry->Handler(Parameter1,
+ Parameter2,
+ Parameter3,
+ Parameter4);
+
+ goto done;
+ }
+ }
+
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: %08X: %p %p %p %p\n",
+ __MODULE__,
+ Code,
+ (PVOID)Parameter1,
+ (PVOID)Parameter2,
+ (PVOID)Parameter3,
+ (PVOID)Parameter4);
+
+ BugCheckDefaultHandler();
+
+done:
+ LogPrintf(LOG_LEVEL_CRITICAL,
+ "%s|BUGCHECK: <====\n",
+ __MODULE__);
+}
+
+#pragma warning(pop)
+
+NTSTATUS
+BugCheckInitialize(
+ VOID)
+{
+ NTSTATUS status;
+
+ KeInitializeCallbackRecord(&BugCheckBugCheckCallbackRecord);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (!KeRegisterBugCheckCallback(&BugCheckBugCheckCallbackRecord,
+ BugCheckBugCheckCallback,
+ NULL,
+ 0,
+ (PUCHAR)__MODULE__))
+ goto fail1;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
--- /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 _XEN_BUG_CHECK_H
+#define _XEN_BUG_CHECK_H
+
+#include <ntddk.h>
+
+extern NTSTATUS
+BugCheckInitialize(
+ VOID);
+
+extern VOID
+BugCheckTeardown(
+ VOID
+ );
+
+#endif // _XEN_BUG_CHECK_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.
- */
-
-#define XEN_API extern
-
-#include <ntddk.h>
-#include <xen.h>
-#include <bugcodes.h>
-
-#include "hypercall.h"
-#include "module.h"
-#include "debug.h"
-#include "log.h"
-#include "assert.h"
-
-static KBUGCHECK_CALLBACK_RECORD DebugBugCheckCallbackRecord;
-
-VOID
-DebugTeardown(
- VOID
- )
-{
- (VOID) KeDeregisterBugCheckCallback(&DebugBugCheckCallbackRecord);
-}
-
-#pragma warning(push)
-#pragma warning(disable: 6320) // Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled.
-#pragma warning(disable: 6322) // Empty _except block.
-
-static DECLSPEC_NOINLINE VOID
-DebugDumpExceptionRecord(
- IN PEXCEPTION_RECORD Exception
- )
-{
- __try {
- while (Exception != NULL) {
- ULONG Index;
-
- LogQemuPrintf("%s|BUGCHECK: EXCEPTION (%p):\n", __MODULE__,
- Exception);
- LogQemuPrintf("%s|BUGCHECK: - Code = %08X\n", __MODULE__,
- Exception->ExceptionCode);
- LogQemuPrintf("%s|BUGCHECK: - Flags = %08X\n", __MODULE__,
- Exception->ExceptionFlags);
- LogQemuPrintf("%s|BUGCHECK: - Address = %p\n", __MODULE__,
- Exception->ExceptionAddress);
-
- for (Index = 0; Index < Exception->NumberParameters; Index++)
- LogQemuPrintf("%s|BUGCHECK: - Parameter[%u] = %p\n", __MODULE__,
- Index,
- (PVOID)Exception->ExceptionInformation[Index]);
-
- Exception = Exception->ExceptionRecord;
- }
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Nothing to to
- }
-}
-
-#pragma warning(push)
-#pragma warning(disable:6262) // Uses more than 1024 bytes of stack
-
-#if defined(__i386__)
-static DECLSPEC_NOINLINE VOID
-DebugDumpContext(
- IN PCONTEXT Context
- )
-{
- __try {
- LogQemuPrintf("%s|BUGCHECK: CONTEXT (%p):\n", __MODULE__,
- Context);
- LogQemuPrintf("%s|BUGCHECK: - GS = %p\n", __MODULE__,
- (PVOID)Context->SegGs);
- LogQemuPrintf("%s|BUGCHECK: - FS = %p\n", __MODULE__,
- (PVOID)Context->SegFs);
- LogQemuPrintf("%s|BUGCHECK: - ES = %p\n", __MODULE__,
- (PVOID)Context->SegEs);
- LogQemuPrintf("%s|BUGCHECK: - DS = %p\n", __MODULE__,
- (PVOID)Context->SegDs);
- LogQemuPrintf("%s|BUGCHECK: - SS = %p\n", __MODULE__,
- (PVOID)Context->SegSs);
- LogQemuPrintf("%s|BUGCHECK: - CS = %p\n", __MODULE__,
- (PVOID)Context->SegCs);
-
- LogQemuPrintf("%s|BUGCHECK: - EFLAGS = %p\n", __MODULE__,
- (PVOID)Context->EFlags);
-
- LogQemuPrintf("%s|BUGCHECK: - EDI = %p\n", __MODULE__,
- (PVOID)Context->Edi);
- LogQemuPrintf("%s|BUGCHECK: - ESI = %p\n", __MODULE__,
- (PVOID)Context->Esi);
- LogQemuPrintf("%s|BUGCHECK: - EBX = %p\n", __MODULE__,
- (PVOID)Context->Ebx);
- LogQemuPrintf("%s|BUGCHECK: - EDX = %p\n", __MODULE__,
- (PVOID)Context->Edx);
- LogQemuPrintf("%s|BUGCHECK: - ECX = %p\n", __MODULE__,
- (PVOID)Context->Ecx);
- LogQemuPrintf("%s|BUGCHECK: - EAX = %p\n", __MODULE__,
- (PVOID)Context->Eax);
- LogQemuPrintf("%s|BUGCHECK: - EBP = %p\n", __MODULE__,
- (PVOID)Context->Ebp);
- LogQemuPrintf("%s|BUGCHECK: - EIP = %p\n", __MODULE__,
- (PVOID)Context->Eip);
- LogQemuPrintf("%s|BUGCHECK: - ESP = %p\n", __MODULE__,
- (PVOID)Context->Esp);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Nothing to to
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugStackDump(
- IN PCONTEXT Context
- )
-{
-#define PARAMETER_COUNT 3
-#define MAXIMUM_ITERATIONS 20
-
- __try {
- ULONG_PTR EBP;
- ULONG Iteration;
-
- DebugDumpContext(Context);
-
- EBP = (ULONG_PTR)Context->Ebp;
-
- LogQemuPrintf("%s|BUGCHECK: STACK:\n", __MODULE__);
-
- for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
- ULONG_PTR NextEBP;
- ULONG_PTR EIP;
- ULONG_PTR Parameter[PARAMETER_COUNT] = {0};
- ULONG Index;
- PCHAR Name;
- ULONG_PTR Offset;
-
- NextEBP = *(PULONG_PTR)EBP;
- EIP = *(PULONG_PTR)(EBP + 4);
-
- if (EIP == 0)
- break;
-
- Index = 0;
- Offset = 8;
- for (;;) {
- if (EBP + Offset >= NextEBP)
- break;
-
- if (Index == PARAMETER_COUNT)
- break;
-
- Parameter[Index] = *(PULONG_PTR)(EBP + Offset);
-
- Index += 1;
- Offset += 4;
- }
-
- ModuleLookup(EIP, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p) %s + %p\n", __MODULE__,
- EBP,
- (PVOID)Parameter[0],
- (PVOID)Parameter[1],
- (PVOID)Parameter[2],
- Name,
- (PVOID)Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p) %p\n", __MODULE__,
- EBP,
- (PVOID)Parameter[0],
- (PVOID)Parameter[1],
- (PVOID)Parameter[2],
- (PVOID)EIP);
-
- EBP = NextEBP;
- }
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // End of stack
- }
-
-#undef MAXIMUM_ITERATIONS
-#undef PARAMETER_COUNT
-}
-#elif defined(__x86_64__)
-static DECLSPEC_NOINLINE VOID
-DebugDumpContext(
- IN PCONTEXT Context
- )
-{
- __try {
- LogQemuPrintf("%s|BUGCHECK: CONTEXT (%p):\n", __MODULE__,
- Context);
- LogQemuPrintf("%s|BUGCHECK: - GS = %p\n", __MODULE__,
- (PVOID)Context->SegGs);
- LogQemuPrintf("%s|BUGCHECK: - FS = %p\n", __MODULE__,
- (PVOID)Context->SegFs);
- LogQemuPrintf("%s|BUGCHECK: - ES = %p\n", __MODULE__,
- (PVOID)Context->SegEs);
- LogQemuPrintf("%s|BUGCHECK: - DS = %p\n", __MODULE__,
- (PVOID)Context->SegDs);
- LogQemuPrintf("%s|BUGCHECK: - SS = %p\n", __MODULE__,
- (PVOID)Context->SegSs);
- LogQemuPrintf("%s|BUGCHECK: - CS = %p\n", __MODULE__,
- (PVOID)Context->SegCs);
-
- LogQemuPrintf("%s|BUGCHECK: - EFLAGS = %p\n", __MODULE__,
- (PVOID)Context->EFlags);
-
- LogQemuPrintf("%s|BUGCHECK: - RDI = %p\n", __MODULE__,
- (PVOID)Context->Rdi);
- LogQemuPrintf("%s|BUGCHECK: - RSI = %p\n", __MODULE__,
- (PVOID)Context->Rsi);
- LogQemuPrintf("%s|BUGCHECK: - RBX = %p\n", __MODULE__,
- (PVOID)Context->Rbx);
- LogQemuPrintf("%s|BUGCHECK: - RDX = %p\n", __MODULE__,
- (PVOID)Context->Rdx);
- LogQemuPrintf("%s|BUGCHECK: - RCX = %p\n", __MODULE__,
- (PVOID)Context->Rcx);
- LogQemuPrintf("%s|BUGCHECK: - RAX = %p\n", __MODULE__,
- (PVOID)Context->Rax);
- LogQemuPrintf("%s|BUGCHECK: - RBP = %p\n", __MODULE__,
- (PVOID)Context->Rbp);
- LogQemuPrintf("%s|BUGCHECK: - RIP = %p\n", __MODULE__,
- (PVOID)Context->Rip);
- LogQemuPrintf("%s|BUGCHECK: - RSP = %p\n", __MODULE__,
- (PVOID)Context->Rsp);
- LogQemuPrintf("%s|BUGCHECK: - R8 = %p\n", __MODULE__,
- (PVOID)Context->R8);
- LogQemuPrintf("%s|BUGCHECK: - R9 = %p\n", __MODULE__,
- (PVOID)Context->R9);
- LogQemuPrintf("%s|BUGCHECK: - R10 = %p\n", __MODULE__,
- (PVOID)Context->R10);
- LogQemuPrintf("%s|BUGCHECK: - R11 = %p\n", __MODULE__,
- (PVOID)Context->R11);
- LogQemuPrintf("%s|BUGCHECK: - R12 = %p\n", __MODULE__,
- (PVOID)Context->R12);
- LogQemuPrintf("%s|BUGCHECK: - R13 = %p\n", __MODULE__,
- (PVOID)Context->R13);
- LogQemuPrintf("%s|BUGCHECK: - R14 = %p\n", __MODULE__,
- (PVOID)Context->R14);
- LogQemuPrintf("%s|BUGCHECK: - R15 = %p\n", __MODULE__,
- (PVOID)Context->R15);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Nothing to to
- }
-}
-
-typedef struct _RUNTIME_FUNCTION {
- ULONG BeginAddress;
- ULONG EndAddress;
- ULONG UnwindData;
-} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-
-#define UNWIND_HISTORY_TABLE_SIZE 12
-
-typedef struct _UNWIND_HISTORY_TABLE_ENTRY {
- ULONG64 ImageBase;
- PRUNTIME_FUNCTION FunctionEntry;
-} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
-
-#define UNWIND_HISTORY_TABLE_NONE 0
-#define UNWIND_HISTORY_TABLE_GLOBAL 1
-#define UNWIND_HISTORY_TABLE_LOCAL 2
-
-typedef struct _UNWIND_HISTORY_TABLE {
- ULONG Count;
- UCHAR Search;
- UCHAR RaiseStatusIndex;
- BOOLEAN Unwind;
- BOOLEAN Exception;
- ULONG64 LowAddress;
- ULONG64 HighAddress;
- UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
-} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
-
-extern PRUNTIME_FUNCTION
-RtlLookupFunctionEntry(
- __in ULONG64 ControlPc,
- __out PULONG64 ImageBase,
- __inout_opt PUNWIND_HISTORY_TABLE HistoryTable OPTIONAL
- );
-
-#pragma prefast(suppress:28301) // No annotations
-typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) (
- __in struct _EXCEPTION_RECORD *ExceptionRecord,
- __in PVOID EstablisherFrame,
- __inout struct _CONTEXT *ContextRecord,
- __inout PVOID DispatcherContext
- );
-
-#pragma warning(push)
-#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
-
-typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
- union {
- PM128A FloatingContext[16];
- struct {
- PM128A Xmm0;
- PM128A Xmm1;
- PM128A Xmm2;
- PM128A Xmm3;
- PM128A Xmm4;
- PM128A Xmm5;
- PM128A Xmm6;
- PM128A Xmm7;
- PM128A Xmm8;
- PM128A Xmm9;
- PM128A Xmm10;
- PM128A Xmm11;
- PM128A Xmm12;
- PM128A Xmm13;
- PM128A Xmm14;
- PM128A Xmm15;
- };
- };
-
- union {
- PULONG64 IntegerContext[16];
- struct {
- PULONG64 Rax;
- PULONG64 Rcx;
- PULONG64 Rdx;
- PULONG64 Rbx;
- PULONG64 Rsp;
- PULONG64 Rbp;
- PULONG64 Rsi;
- PULONG64 Rdi;
- PULONG64 R8;
- PULONG64 R9;
- PULONG64 R10;
- PULONG64 R11;
- PULONG64 R12;
- PULONG64 R13;
- PULONG64 R14;
- PULONG64 R15;
- };
- };
-} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
-
-#pragma warning(pop)
-
-#define UNW_FLAG_NHANDLER 0
-#define UNW_FLAG_EHANDLER 1
-#define UNW_FLAG_UHANDLER 2
-
-extern PEXCEPTION_ROUTINE
-RtlVirtualUnwind(
- __in ULONG HandlerType,
- __in ULONG64 ImageBase,
- __in ULONG64 ControlPc,
- __in PRUNTIME_FUNCTION FunctionEntry,
- __inout PCONTEXT ContextRecord,
- __out PVOID *HandlerData,
- __out PULONG64 EstablisherFrame,
- __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
- );
-
-static DECLSPEC_NOINLINE VOID
-DebugStackDump(
- IN PCONTEXT Context
- )
-{
-#define PARAMETER_COUNT 4
-#define MAXIMUM_ITERATIONS 20
-
- __try {
- ULONG Iteration;
-
- DebugDumpContext(Context);
-
- LogQemuPrintf("%s|BUGCHECK: STACK:\n", __MODULE__);
-
- for (Iteration = 0; Iteration < MAXIMUM_ITERATIONS; Iteration++) {
- PRUNTIME_FUNCTION FunctionEntry;
- ULONG_PTR ImageBase;
- ULONG_PTR RIP;
- ULONG_PTR RSP;
- ULONG_PTR Parameter[PARAMETER_COUNT] = {0};
- ULONG Index;
- PCHAR Name;
- ULONG_PTR Offset;
-
- if (Context->Rip == 0)
- break;
-
- FunctionEntry = RtlLookupFunctionEntry(Context->Rip,
- &ImageBase,
- NULL);
-
- if (FunctionEntry != NULL) {
- CONTEXT UnwindContext;
- ULONG64 ControlPc;
- PVOID HandlerData;
- ULONG64 EstablisherFrame;
- KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
-
- UnwindContext = *Context;
- ControlPc = Context->Rip;
- HandlerData = NULL;
- EstablisherFrame = 0;
- RtlZeroMemory(&ContextPointers, sizeof (KNONVOLATILE_CONTEXT_POINTERS));
-
- (VOID) RtlVirtualUnwind(UNW_FLAG_UHANDLER,
- ImageBase,
- ControlPc,
- FunctionEntry,
- &UnwindContext,
- &HandlerData,
- &EstablisherFrame,
- &ContextPointers);
-
- *Context = UnwindContext;
- } else {
- Context->Rip = *(PULONG64)(Context->Rsp);
- Context->Rsp += sizeof (ULONG64);
- }
-
- RSP = Context->Rsp;
- RIP = Context->Rip;
-
- Index = 0;
- Offset = 0;
- for (;;) {
- if (Index == PARAMETER_COUNT)
- break;
-
- Parameter[Index] = *(PULONG64)(RSP + Offset);
-
- Index += 1;
- Offset += 8;
- }
-
- ModuleLookup(RIP, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p %p) %s + %p\n", __MODULE__,
- RSP,
- (PVOID)Parameter[0],
- (PVOID)Parameter[1],
- (PVOID)Parameter[2],
- (PVOID)Parameter[3],
- Name,
- (PVOID)Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: %p: (%p %p %p %p) %p\n", __MODULE__,
- RSP,
- (PVOID)Parameter[0],
- (PVOID)Parameter[1],
- (PVOID)Parameter[2],
- (PVOID)Parameter[3],
- (PVOID)RIP);
- }
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-#else
-#error 'Unrecognised architecture'
-#endif
-
-extern VOID
-RtlCaptureContext(
- __out PCONTEXT Context
- );
-
-static DECLSPEC_NOINLINE VOID
-DebugIrqlNotLessOrEqual(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- CONTEXT Context;
- PVOID Memory = (PVOID)Parameter1;
- KIRQL Irql = (KIRQL)Parameter2;
- ULONG_PTR Access = Parameter3;
- PVOID Address = (PVOID)Parameter4;
- PCHAR Name;
- ULONG_PTR Offset;
-
- LogQemuPrintf("%s|BUGCHECK: MEMORY REFERENCED: %p\n", __MODULE__,
- Memory);
- LogQemuPrintf("%s|BUGCHECK: IRQL: %02x\n", __MODULE__,
- Irql);
- LogQemuPrintf("%s|BUGCHECK: ACCESS: %p\n", __MODULE__,
- (PVOID)Access);
-
- ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: ADDRESS: %s + %p\n", __MODULE__,
- Name,
- Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: ADDRESS: %p\n", __MODULE__,
- Address);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugDriverIrqlNotLessOrEqual(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- CONTEXT Context;
- PVOID Memory = (PVOID)Parameter1;
- KIRQL Irql = (KIRQL)Parameter2;
- ULONG_PTR Access = Parameter3;
- PVOID Address = (PVOID)Parameter4;
- PCHAR Name;
- ULONG_PTR Offset;
-
- LogQemuPrintf("%s|BUGCHECK: MEMORY REFERENCED: %p\n", __MODULE__,
- Memory);
- LogQemuPrintf("%s|BUGCHECK: IRQL: %02X\n", __MODULE__,
- Irql);
- LogQemuPrintf("%s|BUGCHECK: ACCESS: %p\n", __MODULE__,
- (PVOID)Access);
-
- ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: ADDRESS: %s + %p\n", __MODULE__,
- Name,
- Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: ADDRESS: %p\n", __MODULE__,
- Address);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugSystemServiceException(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- PEXCEPTION_RECORD Exception = (PEXCEPTION_RECORD)Parameter2;
- PCONTEXT Context = (PCONTEXT)Parameter3;
-
- UNREFERENCED_PARAMETER(Parameter1);
- UNREFERENCED_PARAMETER(Parameter4);
-
- DebugDumpExceptionRecord(Exception);
-
- DebugStackDump(Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugSystemThreadExceptionNotHandled(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- ULONG Code = (ULONG)Parameter1;
- PVOID Address = (PVOID)Parameter2;
- PEXCEPTION_RECORD Exception = (PEXCEPTION_RECORD)Parameter3;
- PCONTEXT Context = (PCONTEXT)Parameter4;
- PCHAR Name;
- ULONG_PTR Offset;
-
- ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: %08X AT %s + %p\n", __MODULE__,
- Code,
- Name,
- Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: %08X AT %p\n", __MODULE__,
- Code,
- Name,
- Address);
-
- DebugDumpExceptionRecord(Exception);
-
- DebugStackDump(Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugKernelModeExceptionNotHandled(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- CONTEXT Context;
- ULONG Code = (ULONG)Parameter1;
- PVOID Address = (PVOID)Parameter2;
- PCHAR Name;
- ULONG_PTR Offset;
-
- UNREFERENCED_PARAMETER(Parameter3);
- UNREFERENCED_PARAMETER(Parameter4);
-
- ModuleLookup((ULONG_PTR)Address, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: %08X AT %s + %p\n", __MODULE__,
- Code,
- Name,
- Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: %08X AT %p\n", __MODULE__,
- Code,
- Name,
- Address);
-
- LogQemuPrintf("%s|BUGCHECK: - Code = %08X\n", __MODULE__,
- Code);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugCriticalObjectTermination(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- ULONG Type = (ULONG)Parameter1;
- PVOID Object = (PVOID)Parameter2;
- PCHAR Name = (PCHAR)Parameter3;
- PCHAR Reason = (PCHAR)Parameter4;
- CONTEXT Context;
-
- LogQemuPrintf("%s|BUGCHECK: Type = %08X\n", __MODULE__,
- Type);
- LogQemuPrintf("%s|BUGCHECK: Object = %p\n", __MODULE__,
- Object);
- LogQemuPrintf("%s|BUGCHECK: Name = %s\n", __MODULE__,
- Name);
- LogQemuPrintf("%s|BUGCHECK: Reason = %s\n", __MODULE__,
- Reason);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugInaccessibleBootDevice(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- PUNICODE_STRING Unicode = (PUNICODE_STRING)Parameter1;
- CONTEXT Context;
-
- UNREFERENCED_PARAMETER(Parameter2);
- UNREFERENCED_PARAMETER(Parameter3);
- UNREFERENCED_PARAMETER(Parameter4);
-
- LogQemuPrintf("%s|BUGCHECK: %wZ\n", __MODULE__,
- Unicode);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugDriverPowerStateFailure(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- ULONG_PTR Code = Parameter1;
-
- UNREFERENCED_PARAMETER(Parameter3);
-
- LogQemuPrintf("%s|BUGCHECK: Code %08x\n", __MODULE__,
- Code);
-
- switch (Code) {
- case 0x1: {
- PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parameter2;
-
- LogQemuPrintf("%s|BUGCHECK: OUTSTANDING IRP (Device Object %p)\n", __MODULE__,
- DeviceObject);
-
- break;
- }
- case 0x3: {
- PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Parameter2;
- PIRP Irp = (PIRP)Parameter4;
- PIO_STACK_LOCATION StackLocation;
- LONG Index;
-
- LogQemuPrintf("%s|BUGCHECK: OUTSTANDING IRP %p (Device Object %p)\n", __MODULE__,
- Irp,
- DeviceObject);
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
- LogQemuPrintf("%s|BUGCHECK: IRP STACK:\n", __MODULE__);
-
- for (Index = 0; Index <= Irp->StackCount; Index++) {
- PCHAR Name;
- ULONG_PTR Offset;
-
- LogQemuPrintf("%s|BUGCHECK: [%c%u] %02x %02x %02x %02x\n", __MODULE__,
- (Index == Irp->CurrentLocation) ? '>' : ' ',
- Index,
- StackLocation->MajorFunction,
- StackLocation->MinorFunction,
- StackLocation->Flags,
- StackLocation->Control);
-
- ModuleLookup((ULONG_PTR)StackLocation->CompletionRoutine, &Name, &Offset);
-
- if (Name != NULL)
- LogQemuPrintf("%s|BUGCHECK: [%c%u] CompletionRoutine = %s + %p\n", __MODULE__,
- (Index == Irp->CurrentLocation) ? '>' : ' ',
- Index,
- Name,
- (PVOID)Offset);
- else
- LogQemuPrintf("%s|BUGCHECK: [%c%u] CompletionRoutine = %p\n", __MODULE__,
- (Index == Irp->CurrentLocation) ? '>' : ' ',
- Index,
- StackLocation->CompletionRoutine);
-
- LogQemuPrintf("%s|BUGCHECK: [%c%u] Context = %p\n", __MODULE__,
- (Index == Irp->CurrentLocation) ? '>' : ' ',
- Index,
- StackLocation->Context);
-
- StackLocation++;
- }
-
- break;
- }
- default:
- break;
- }
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-static DECLSPEC_NOINLINE VOID
-DebugAssertionFailure(
- IN ULONG_PTR Parameter1,
- IN ULONG_PTR Parameter2,
- IN ULONG_PTR Parameter3,
- IN ULONG_PTR Parameter4
- )
-{
- __try {
- PCHAR Text = (PCHAR)Parameter1;
- PCHAR File = (PCHAR)Parameter2;
- ULONG Line = (ULONG)Parameter3;
- CONTEXT Context;
-
- UNREFERENCED_PARAMETER(Parameter4);
-
- LogQemuPrintf("%s|BUGCHECK: FILE: %s LINE: %u\n", __MODULE__,
- File,
- Line);
- LogQemuPrintf("%s|BUGCHECK: TEXT: %s\n", __MODULE__,
- Text);
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-struct _BUG_CODE_ENTRY {
- ULONG Code;
- const CHAR *Name;
- VOID (*Handler)(ULONG_PTR, ULONG_PTR, ULONG_PTR, ULONG_PTR);
-};
-
-#define DEFINE_HANDLER(_Code, _Function) \
- { (_Code), #_Code, (_Function) }
-
-struct _BUG_CODE_ENTRY BugCodeTable[] = {
- DEFINE_HANDLER(IRQL_NOT_LESS_OR_EQUAL, DebugIrqlNotLessOrEqual),
- DEFINE_HANDLER(DRIVER_IRQL_NOT_LESS_OR_EQUAL, DebugDriverIrqlNotLessOrEqual),
- DEFINE_HANDLER(SYSTEM_SERVICE_EXCEPTION, DebugSystemServiceException),
- DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED, DebugSystemThreadExceptionNotHandled),
- DEFINE_HANDLER(SYSTEM_THREAD_EXCEPTION_NOT_HANDLED_M, DebugSystemThreadExceptionNotHandled),
- DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED, DebugKernelModeExceptionNotHandled),
- DEFINE_HANDLER(KERNEL_MODE_EXCEPTION_NOT_HANDLED_M, DebugKernelModeExceptionNotHandled),
- DEFINE_HANDLER(CRITICAL_OBJECT_TERMINATION, DebugCriticalObjectTermination),
- DEFINE_HANDLER(INACCESSIBLE_BOOT_DEVICE, DebugInaccessibleBootDevice),
- DEFINE_HANDLER(DRIVER_POWER_STATE_FAILURE, DebugDriverPowerStateFailure),
- DEFINE_HANDLER(ASSERTION_FAILURE, DebugAssertionFailure),
- { 0, NULL, NULL }
-};
-
-static DECLSPEC_NOINLINE VOID
-DebugDefaultHandler(
- VOID
- )
-{
- __try {
- CONTEXT Context;
-
- RtlCaptureContext(&Context);
- DebugStackDump(&Context);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- // Error of some kind
- }
-}
-
-#pragma warning(pop)
-
-KBUGCHECK_CALLBACK_ROUTINE DebugBugCheckCallback;
-
-VOID
-DebugBugCheckCallback(
- IN PVOID Argument,
- IN ULONG Length
- )
-{
- extern PULONG_PTR KiBugCheckData;
- ULONG Code;
- ULONG_PTR Parameter1;
- ULONG_PTR Parameter2;
- ULONG_PTR Parameter3;
- ULONG_PTR Parameter4;
- struct _BUG_CODE_ENTRY *Entry;
-
- UNREFERENCED_PARAMETER(Argument);
- UNREFERENCED_PARAMETER(Length);
-
- (VOID) SchedShutdownCode(SHUTDOWN_crash);
-
- LogQemuPrintf("%s|BUGCHECK: ====>\n", __MODULE__);
-
- Code = (ULONG)KiBugCheckData[0];
- Parameter1 = KiBugCheckData[1];
- Parameter2 = KiBugCheckData[2];
- Parameter3 = KiBugCheckData[3];
- Parameter4 = KiBugCheckData[4];
-
- for (Entry = BugCodeTable; Entry->Code != 0; Entry++) {
- if (Code == Entry->Code) {
- LogQemuPrintf("%s|BUGCHECK: %s: %p %p %p %p\n", __MODULE__,
- Entry->Name,
- (PVOID)Parameter1,
- (PVOID)Parameter2,
- (PVOID)Parameter3,
- (PVOID)Parameter4);
-
- Entry->Handler(Parameter1,
- Parameter2,
- Parameter3,
- Parameter4);
-
- goto done;
- }
- }
-
- LogQemuPrintf("%s|BUGCHECK: %08X: %p %p %p %p\n", __MODULE__,
- Code,
- (PVOID)Parameter1,
- (PVOID)Parameter2,
- (PVOID)Parameter3,
- (PVOID)Parameter4);
-
- DebugDefaultHandler();
-
-done:
- LogQemuPrintf("%s|BUGCHECK: <====\n", __MODULE__);
-}
-
-#pragma warning(pop)
-
-NTSTATUS
-DebugInitialize(
- VOID)
-{
- NTSTATUS status;
-
- KeInitializeCallbackRecord(&DebugBugCheckCallbackRecord);
-
- status = STATUS_UNSUCCESSFUL;
- if (!KeRegisterBugCheckCallback(&DebugBugCheckCallbackRecord,
- DebugBugCheckCallback,
- NULL,
- 0,
- (PUCHAR)__MODULE__))
- goto fail1;
-
- Info("callback registered\n");
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
+++ /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 _XEN_DEBUG_H
-#define _XEN_DEBUG_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-DebugInitialize(
- VOID);
-
-extern VOID
-DebugTeardown(
- VOID
- );
-
-#endif // _XEN_DEBUG_H
#include <xen.h>
#include "hypercall.h"
-#include "debug.h"
-#include "dump.h"
+#include "log.h"
#include "module.h"
#include "process.h"
-#include "unplug.h"
#include "system.h"
-#include "log.h"
+#include "bug_check.h"
+#include "dbg_print.h"
#include "assert.h"
#include "version.h"
extern PULONG InitSafeBootMode;
-XEN_API
-const CHAR *
-XenVersion = MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR;
+typedef struct _XEN_DRIVER {
+ PLOG_DISPOSITION TraceDisposition;
+ PLOG_DISPOSITION InfoDisposition;
+} XEN_DRIVER, *PXEN_DRIVER;
+
+static XEN_DRIVER Driver;
+
+static VOID
+DriverOutputBuffer(
+ IN PVOID Argument,
+ IN PCHAR Buffer,
+ IN ULONG Length
+ )
+{
+ ULONG_PTR Port = (ULONG_PTR)Argument;
+
+ __outbytestring((USHORT)Port, (PUCHAR)Buffer, Length);
+}
+
+#define XEN_PORT 0xE9
+#define QEMU_PORT 0x12
NTSTATUS
DllInitialize(
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
- LogInitialize();
+ __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");
if (*InitSafeBootMode > 0)
goto done;
- SystemGetInformation();
-
- status = HypercallInitialize();
+ status = LogInitialize();
if (!NT_SUCCESS(status))
goto fail1;
- status = DebugInitialize();
+ status = LogAddDisposition(LOG_LEVEL_TRACE |
+ LOG_LEVEL_CRITICAL,
+ DriverOutputBuffer,
+ (PVOID)XEN_PORT,
+ &Driver.TraceDisposition);
+ ASSERT(NT_SUCCESS(status));
+
+ status = LogAddDisposition(LOG_LEVEL_INFO |
+ LOG_LEVEL_WARNING |
+ LOG_LEVEL_ERROR |
+ LOG_LEVEL_CRITICAL,
+ DriverOutputBuffer,
+ (PVOID)QEMU_PORT,
+ &Driver.InfoDisposition);
+ ASSERT(NT_SUCCESS(status));
+
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+ MAJOR_VERSION,
+ MINOR_VERSION,
+ MICRO_VERSION,
+ BUILD_NUMBER,
+ DAY,
+ MONTH,
+ YEAR);
+
+ SystemGetInformation();
+
+ status = HypercallInitialize();
if (!NT_SUCCESS(status))
goto fail2;
- status = DumpInitialize();
+ status = BugCheckInitialize();
if (!NT_SUCCESS(status))
goto fail3;
if (!NT_SUCCESS(status))
goto fail5;
- UnplugInitialize();
-
done:
+ Trace("<====\n");
+
return STATUS_SUCCESS;
fail5:
fail4:
Error("fail4\n");
- DumpTeardown();
+ BugCheckTeardown();
fail3:
Error("fail3\n");
- DebugTeardown();
+ HypercallTeardown();
fail2:
Error("fail2\n");
- HypercallTeardown();
+ LogRemoveDisposition(Driver.InfoDisposition);
+ Driver.InfoDisposition = NULL;
+
+ LogRemoveDisposition(Driver.TraceDisposition);
+ Driver.TraceDisposition = NULL;
+
+ LogTeardown();
fail1:
Error("fail1 (%08x)", status);
- LogTeardown();
+ ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER)));
return status;
}
VOID
)
{
- Info("%s (%s)\n",
- MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
- DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ Trace("====>\n");
if (*InitSafeBootMode > 0)
goto done;
- UnplugTeardown();
-
ProcessTeardown();
ModuleTeardown();
- DumpTeardown();
-
- DebugTeardown();
+ BugCheckTeardown();
HypercallTeardown();
-done:
+ LogRemoveDisposition(Driver.InfoDisposition);
+ Driver.InfoDisposition = NULL;
+
+ LogRemoveDisposition(Driver.TraceDisposition);
+ Driver.TraceDisposition = NULL;
+
LogTeardown();
+done:
+ ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER)));
+
+ Trace("<====\n");
+
return 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.
- */
-
-#include <ntddk.h>
-#include <xen.h>
-
-#include "dump.h"
-#include "log.h"
-#include "assert.h"
-
-//
-// Crash dumps via QEMU
-//
-// To enable you need to customize /opt/xensource/libexec/qemu-dm-wrapper in dom0 to add the following
-// arguments to the qemu command line:
-//
-// -dumpdir <directory> -dumpquota <quota>
-//
-// <directory> is best pointed at an empty directory. Files will be created with numeric names starting at 0.
-// <quota> should be the total size in MB of all possible crash dump files. I.e. once sufficient crash dumps have
-// occurred to fill this quota, no more will be allowed until sufficient space is cleared in <directory>. This is
-// to prevent dump files (which can be very large) from overrunning dom0's filesystem.
-//
-
-static KBUGCHECK_REASON_CALLBACK_RECORD DumpBugCheckReasonCallbackRecord;
-
-VOID
-DumpTeardown(
- VOID
- )
-{
- (VOID) KeDeregisterBugCheckReasonCallback(&DumpBugCheckReasonCallbackRecord);
-}
-
-static PVOID PortEB = ((PVOID)(ULONG_PTR)0xeb);
-static PVOID PortEC = ((PVOID)(ULONG_PTR)0xec);
-
-#define DUMP_VERSION 0x01
-
-#define DUMP_IO_REGISTERED 0x00
-#define DUMP_IO_OPEN 0x01
-#define DUMP_IO_CLOSE 0x02
-
-static KBUGCHECK_DUMP_IO_TYPE DumpIoType = KbDumpIoInvalid;
-
-static FORCEINLINE VOID
-__DumpPortOpen(
- VOID
- )
-{
- Info("====>\n");
- WRITE_PORT_UCHAR(PortEB, DUMP_IO_OPEN);
- Info("<====\n");
-}
-
-static FORCEINLINE VOID
-__DumpPortClose(
- VOID
- )
-{
- Info("====>\n");
- WRITE_PORT_UCHAR(PortEB, DUMP_IO_CLOSE);
- Info("<====\n");
-}
-
-#define IS_PAGE_ALIGNED(_Address) (((ULONG_PTR)(_Address) & (PAGE_SIZE - 1)) == 0)
-
-static VOID
-DumpPortWrite(
- IN ULONG64 Offset,
- IN PVOID Buffer,
- IN ULONG Length
- )
-{
- PHYSICAL_ADDRESS Address;
-
- ASSERT(Offset == (ULONG64)-1);
- ASSERT(IS_PAGE_ALIGNED(Buffer));
- ASSERT(IS_PAGE_ALIGNED(Length));
-
- //
- // Sometimes Windows passes us virtual addresses, sometimes it passes
- // physical addresses. It doesn't tell us which it's handing us, and
- // how this plays with PAE is anybody's guess.
- //
- Address = MmGetPhysicalAddress(Buffer);
- if (Address.QuadPart == 0)
- Address.QuadPart = (ULONG_PTR)Buffer;
-
- Address.QuadPart >>= PAGE_SHIFT;
- ASSERT3U(Address.HighPart, ==, 0);
-
- for (Length >>= PAGE_SHIFT; Length != 0; Length--)
- WRITE_PORT_ULONG(PortEC, Address.LowPart++);
-}
-
-static const CHAR *
-DumpIoTypeName(
- IN KBUGCHECK_DUMP_IO_TYPE Type
- )
-{
-#define _IO_TYPE_NAME(_Type) \
- case KbDumpIo ## _Type: \
- return #_Type;
-
- switch (Type) {
- _IO_TYPE_NAME(Invalid);
- _IO_TYPE_NAME(Header);
- _IO_TYPE_NAME(Body);
- _IO_TYPE_NAME(SecondaryData);
- _IO_TYPE_NAME(Complete);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _IO_TYPE_NAME
-}
-
-KBUGCHECK_REASON_CALLBACK_ROUTINE DumpBugCheckReasonCallback;
-
-VOID
-DumpBugCheckReasonCallback(
- IN KBUGCHECK_CALLBACK_REASON Reason,
- IN PKBUGCHECK_REASON_CALLBACK_RECORD Record,
- IN OUT PVOID ReasonSpecificData,
- IN ULONG ReasonSpecificDataLength
- )
-{
- PKBUGCHECK_DUMP_IO DumpIo = (PKBUGCHECK_DUMP_IO)ReasonSpecificData;
-
- UNREFERENCED_PARAMETER(ReasonSpecificDataLength);
-
- ASSERT3U(Reason, ==, KbCallbackDumpIo);
- ASSERT3P(Record, ==, &DumpBugCheckReasonCallbackRecord);
- ASSERT(DumpIo != NULL);
-
- switch (DumpIo->Type) {
- case KbDumpIoHeader:
- ASSERT(DumpIoType == KbDumpIoInvalid ||
- DumpIoType == KbDumpIoHeader);
- DumpIoType = KbDumpIoHeader;
-
- __DumpPortOpen();
-
- DumpPortWrite(DumpIo->Offset,
- DumpIo->Buffer,
- DumpIo->BufferLength);
- break;
-
- case KbDumpIoBody:
- ASSERT(DumpIoType == KbDumpIoHeader ||
- DumpIoType == KbDumpIoBody);
- DumpIoType = KbDumpIoBody;
-
- DumpPortWrite(DumpIo->Offset,
- DumpIo->Buffer,
- DumpIo->BufferLength);
- break;
-
- case KbDumpIoSecondaryData:
- ASSERT(DumpIoType == KbDumpIoBody ||
- DumpIoType == KbDumpIoSecondaryData);
- DumpIoType = KbDumpIoSecondaryData;
-
- DumpPortWrite(DumpIo->Offset,
- DumpIo->Buffer,
- DumpIo->BufferLength);
- break;
-
- case KbDumpIoComplete:
- ASSERT3U(DumpIoType, ==, KbDumpIoSecondaryData);
- DumpIoType = KbDumpIoComplete;
-
- __DumpPortClose();
- break;
-
- case KbDumpIoInvalid:
- default:
- ASSERT(FALSE);
- break;
- }
-}
-
-NTSTATUS
-DumpInitialize(
- VOID
- )
-{
- UCHAR Version;
- NTSTATUS status;
-
- Version = READ_PORT_UCHAR(PortEB);
-
- if (Version != DUMP_VERSION)
- goto done;
-
- KeInitializeCallbackRecord(&DumpBugCheckReasonCallbackRecord);
-
- status = STATUS_UNSUCCESSFUL;
- if (!KeRegisterBugCheckReasonCallback(&DumpBugCheckReasonCallbackRecord,
- DumpBugCheckReasonCallback,
- KbCallbackDumpIo,
- (PUCHAR)__MODULE__))
- goto fail1;
-
- Info("callback registered\n");
-
-done:
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
+++ /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 _XEN_DUMP_H
-#define _XEN_DUMP_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-DumpInitialize(
- VOID);
-
-extern VOID
-DumpTeardown(
- VOID
- );
-
-#endif // _XEN_DUMP_H
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE LONG_PTR
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE LONG_PTR
+++ /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 _XEN_HIGH_H
-#define _XEN_HIGH_H
-
-#include <ntddk.h>
-
-#pragma warning(disable:4127) // conditional expression is constant
-
-typedef LONG HIGH_LOCK, *PHIGH_LOCK;
-
-#define LOCK_MAGIC 0xFEEDFACE
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_raisesIRQL(HIGH_LEVEL)
-__drv_savesIRQL
-KIRQL
-__AcquireHighLock(
- IN PHIGH_LOCK Lock
- )
-{
- KIRQL Irql;
-
- KeRaiseIrql(HIGH_LEVEL, &Irql);
-
- while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
- _mm_pause();
-
- KeMemoryBarrier();
-
- return Irql;
-}
-
-#define AcquireHighLock(_Lock, _Irql) \
- do { \
- *(_Irql) = __AcquireHighLock(_Lock); \
- } while (FALSE)
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_requiresIRQL(HIGH_LEVEL)
-VOID
-ReleaseHighLock(
- IN PHIGH_LOCK Lock,
- IN __drv_restoresIRQL KIRQL Irql
- )
-{
- KeMemoryBarrier();
-
- InterlockedExchange(Lock, 0);
- KeLowerIrql(Irql);
-}
-
-static FORCEINLINE
-VOID
-InitializeHighLock(
- IN PHIGH_LOCK Lock
- )
-{
- RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
-}
-
-#endif // _XEN_HIGH_H
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE LONG_PTR
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define MAXIMUM_HYPERCALL_PFN_COUNT 2
#include <ntddk.h>
#include <stdlib.h>
-#include <xen.h>
#include "log.h"
#include "assert.h"
#define LOG_BUFFER_SIZE 256
-static UCHAR LogBuffer[LOG_BUFFER_SIZE];
-static ULONG LogOffset;
-static HIGH_LOCK LogLock;
+struct _LOG_DISPOSITION {
+ LOG_LEVEL Mask;
+ VOID (*Function)(PVOID, PCHAR, ULONG);
+ PVOID Argument;
+};
+
+#define LOG_MAXIMUM_DISPOSITION 8
+
+typedef struct _LOG_CONTEXT {
+ LONG References;
+ BOOLEAN Enabled;
+ CHAR Buffer[LOG_BUFFER_SIZE];
+ ULONG Offset;
+ LOG_DISPOSITION Disposition[LOG_MAXIMUM_DISPOSITION];
+ HIGH_LOCK Lock;
+} LOG_CONTEXT, *PLOG_CONTEXT;
+
+static LOG_CONTEXT LogContext;
static FORCEINLINE
__drv_maxIRQL(HIGH_LEVEL)
__drv_savesIRQL
KIRQL
__LogAcquireBuffer(
- VOID
+ IN PLOG_CONTEXT Context
)
{
- return __AcquireHighLock(&LogLock);
+ return __AcquireHighLock(&Context->Lock);
}
-#define LOG_XEN_PORT 0xE9
-#define LOG_QEMU_PORT 0x12
-
static DECLSPEC_NOINLINE VOID
__drv_maxIRQL(HIGH_LEVEL)
__drv_requiresIRQL(HIGH_LEVEL)
__LogReleaseBuffer(
- IN USHORT Port,
+ IN PLOG_CONTEXT Context,
+ IN LOG_LEVEL Level,
IN __drv_restoresIRQL KIRQL Irql
)
{
- __outbytestring(Port, LogBuffer, LogOffset);
+ ULONG Index;
- RtlZeroMemory(LogBuffer, LogOffset);
- LogOffset = 0;
+ for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+ PLOG_DISPOSITION Disposition = &Context->Disposition[Index];
- ReleaseHighLock(&LogLock, Irql);
+ if (Level & Disposition->Mask)
+ Disposition->Function(Disposition->Argument, Context->Buffer, Context->Offset);
+ }
+
+ RtlZeroMemory(Context->Buffer, Context->Offset);
+ Context->Offset = 0;
+
+ ReleaseHighLock(&Context->Lock, Irql);
}
static FORCEINLINE VOID
__LogPut(
- IN CHAR Character
+ IN PLOG_CONTEXT Context,
+ IN CHAR Character
)
{
- ASSERT(LogOffset < LOG_BUFFER_SIZE);
+ ASSERT(Context->Offset < LOG_BUFFER_SIZE);
- LogBuffer[LogOffset++] = Character;
+ Context->Buffer[Context->Offset++] = Character;
}
static DECLSPEC_NOINLINE PCHAR
} while (FALSE)
static DECLSPEC_NOINLINE VOID
-LogCchVPrintf(
- IN LONG Count,
- IN const CHAR *Format,
- IN va_list Arguments
+LogWriteBuffer(
+ IN PLOG_CONTEXT Context,
+ IN LONG Count,
+ IN const CHAR *Format,
+ IN va_list Arguments
)
{
- CHAR Character;
+ CHAR Character;
while ((Character = *Format++) != '\0') {
UCHAR Pad = 0;
BOOLEAN OppositeJustification = FALSE;
if (Character != '%') {
- __LogPut(Character);
+ __LogPut(Context, Character);
goto loop;
}
WCHAR Value;
Value = va_arg(Arguments, WCHAR);
- __LogPut((CHAR)Value);
+ __LogPut(Context, (CHAR)Value);
} else {
CHAR Value;
Value = va_arg(Arguments, CHAR);
- __LogPut(Value);
+ __LogPut(Context, Value);
}
break;
}
Length = (ULONG)strlen(Buffer);
if (!OppositeJustification) {
while (Pad > Length) {
- __LogPut((ZeroPrefix) ? '0' : ' ');
+ __LogPut(Context, (ZeroPrefix) ? '0' : ' ');
--Pad;
}
}
for (Index = 0; Index < Length; Index++)
- __LogPut(Buffer[Index]);
+ __LogPut(Context, Buffer[Index]);
if (OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
if (OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
for (Index = 0; Index < Length; Index++)
- __LogPut((CHAR)Value[Index]);
+ __LogPut(Context, (CHAR)Value[Index]);
if (!OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
if (OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
for (Index = 0; Index < Length; Index++)
- __LogPut(Value[Index]);
+ __LogPut(Context, Value[Index]);
if (!OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
if (OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
for (Index = 0; Index < Length; Index++)
- __LogPut((CHAR)Buffer[Index]);
+ __LogPut(Context, (CHAR)Buffer[Index]);
if (!OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
if (OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
for (Index = 0; Index < Length; Index++)
- __LogPut(Buffer[Index]);
+ __LogPut(Context, Buffer[Index]);
if (!OppositeJustification) {
while (Pad > Length) {
- __LogPut(' ');
+ __LogPut(Context, ' ');
--Pad;
}
}
break;
}
default:
- __LogPut(Character);
+ __LogPut(Context, Character);
break;
}
}
}
-static FORCEINLINE VOID
-__LogXenCchVPrintf(
- IN ULONG Count,
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- KIRQL Irql;
-
- Irql = __LogAcquireBuffer();
-
- LogCchVPrintf(__min(Count, LOG_BUFFER_SIZE),
- Format,
- Arguments);
-
- __LogReleaseBuffer(LOG_XEN_PORT, Irql);
-}
-
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogXenCchVPrintf(
- IN ULONG Count,
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- __LogXenCchVPrintf(Count, Format, Arguments);
-}
-
XEN_API
VOID
-LogXenCchPrintf(
- IN ULONG Count,
- IN const CHAR *Format,
- ...
- )
-{
- va_list Arguments;
-
- va_start(Arguments, Format);
- __LogXenCchVPrintf(Count, Format, Arguments);
- va_end(Arguments);
-}
-
-static FORCEINLINE VOID
-__LogXenVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- KIRQL Irql;
-
- Irql = __LogAcquireBuffer();
-
- LogCchVPrintf(LOG_BUFFER_SIZE,
- Format,
- Arguments);
-
- __LogReleaseBuffer(LOG_XEN_PORT, Irql);
-}
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogXenVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- __LogXenVPrintf(Format, Arguments);
-}
-
-XEN_API
-VOID
-LogXenPrintf(
- IN const CHAR *Format,
- ...
- )
-{
- va_list Arguments;
-
- va_start(Arguments, Format);
- __LogXenVPrintf(Format, Arguments);
- va_end(Arguments);
-}
-
-static FORCEINLINE VOID
-__LogQemuCchVPrintf(
+LogCchVPrintf(
+ IN LOG_LEVEL Level,
IN ULONG Count,
IN const CHAR *Format,
IN va_list Arguments
)
{
+ PLOG_CONTEXT Context = &LogContext;
KIRQL Irql;
- Irql = __LogAcquireBuffer();
+ Irql = __LogAcquireBuffer(Context);
- LogCchVPrintf(__min(Count, LOG_BUFFER_SIZE),
- Format,
- Arguments);
+ LogWriteBuffer(Context,
+ __min(Count, LOG_BUFFER_SIZE),
+ Format,
+ Arguments);
- __LogReleaseBuffer(LOG_QEMU_PORT, Irql);
+ __LogReleaseBuffer(Context, Level, Irql);
}
XEN_API
-DECLSPEC_NOINLINE
VOID
-LogQemuCchVPrintf(
- IN ULONG Count,
+LogVPrintf(
+ IN LOG_LEVEL Level,
IN const CHAR *Format,
IN va_list Arguments
)
{
- __LogQemuCchVPrintf(Count, Format, Arguments);
+ LogCchVPrintf(Level, LOG_BUFFER_SIZE, Format, Arguments);
}
XEN_API
VOID
-LogQemuCchPrintf(
+LogCchPrintf(
+ IN LOG_LEVEL Level,
IN ULONG Count,
IN const CHAR *Format,
...
va_list Arguments;
va_start(Arguments, Format);
- __LogQemuCchVPrintf(Count, Format, Arguments);
+ LogCchVPrintf(Level, Count, Format, Arguments);
va_end(Arguments);
}
-static FORCEINLINE VOID
-__LogQemuVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- KIRQL Irql;
-
- Irql = __LogAcquireBuffer();
-
- LogCchVPrintf(LOG_BUFFER_SIZE,
- Format,
- Arguments);
-
- __LogReleaseBuffer(LOG_QEMU_PORT, Irql);
-}
-
-XEN_API
-DECLSPEC_NOINLINE
-VOID
-LogQemuVPrintf(
- IN const CHAR *Format,
- IN va_list Arguments
- )
-{
- __LogQemuVPrintf(Format, Arguments);
-}
-
XEN_API
VOID
-LogQemuPrintf(
+LogPrintf(
+ IN LOG_LEVEL Level,
IN const CHAR *Format,
...
)
va_list Arguments;
va_start(Arguments, Format);
- __LogQemuVPrintf(Format, Arguments);
+ LogCchVPrintf(Level, LOG_BUFFER_SIZE, Format, Arguments);
va_end(Arguments);
}
ULONG Level
);
-static VOID
+static DECLSPEC_NOINLINE VOID
LogDebugPrint(
IN PANSI_STRING Ansi,
IN ULONG ComponentId,
IN ULONG Level
)
{
+ PLOG_CONTEXT Context = &LogContext;
+ KIRQL Irql;
+ ULONG Index;
+
if (Ansi->Length == 0 || Ansi->Buffer == NULL)
return;
- if (ComponentId == DPFLTR_IHVDRIVER_ID) {
- switch (Level) {
- case DPFLTR_ERROR_LEVEL:
- LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
- break;
-
- case DPFLTR_WARNING_LEVEL:
- LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
- break;
+ if (ComponentId != DPFLTR_IHVDRIVER_ID)
+ return;
- case DPFLTR_INFO_LEVEL:
- LogQemuCchPrintf(Ansi->Length, Ansi->Buffer);
- break;
+ AcquireHighLock(&Context->Lock, &Irql);
- case DPFLTR_TRACE_LEVEL:
- LogXenCchPrintf(Ansi->Length, Ansi->Buffer);
- break;
+ for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+ PLOG_DISPOSITION Disposition = &Context->Disposition[Index];
- default:
- break;
- }
- } else {
- LogXenCchPrintf(Ansi->Length, Ansi->Buffer);
+ if ((1 << Level) & Disposition->Mask)
+ Disposition->Function(Disposition->Argument, Ansi->Buffer, Ansi->Length);
}
-}
-BOOLEAN CallbackInstalled;
-
-#define LOG_ENABLE_FILTER(_Id, _Level) \
- do { \
- DbgSetDebugFilterState((_Id), (_Level), TRUE); \
- DbgPrintEx((_Id), \
- (_Level), \
- "DbgPrint(%s, %s) interception enabled\n", \
-/**/ #_Id, \
-/**/ #_Level); \
- } while (FALSE)
+ ReleaseHighLock(&Context->Lock, Irql);
+}
-static FORCEINLINE VOID
-__LogEnable(
+VOID
+LogTeardown(
VOID
)
{
- NTSTATUS status;
+ PLOG_CONTEXT Context = &LogContext;
- if (!CallbackInstalled) {
- status = DbgSetDebugPrintCallback(LogDebugPrint, TRUE);
- CallbackInstalled = NT_SUCCESS(status) ? TRUE : FALSE;
+ if (Context->Enabled) {
+ (VOID) DbgSetDebugPrintCallback(LogDebugPrint, FALSE);
+ Context->Enabled = FALSE;
}
- LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL);
+ RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK));
- LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_WARNING_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL);
- LOG_ENABLE_FILTER(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL);
-}
+ (VOID) InterlockedDecrement(&Context->References);
-XEN_API
-VOID
-LogEnable(
- VOID
- )
-{
- __LogEnable();
+ ASSERT(IsZeroMemory(Context, sizeof (LOG_CONTEXT)));
}
-static FORCEINLINE VOID
-__LogDisable(
- VOID
+NTSTATUS
+LogAddDisposition(
+ IN LOG_LEVEL Mask,
+ IN VOID (*Function)(PVOID, PCHAR, ULONG),
+ IN PVOID Argument OPTIONAL,
+ OUT PLOG_DISPOSITION *Disposition
)
{
- if (CallbackInstalled) {
- (VOID) DbgSetDebugPrintCallback(LogDebugPrint, FALSE);
- CallbackInstalled = FALSE;
+ PLOG_CONTEXT Context = &LogContext;
+ KIRQL Irql;
+ ULONG Index;
+ NTSTATUS status;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Mask == 0)
+ goto fail1;
+
+ AcquireHighLock(&Context->Lock, &Irql);
+
+ status = STATUS_UNSUCCESSFUL;
+ for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+ *Disposition = &Context->Disposition[Index];
+
+ if ((*Disposition)->Mask == 0) {
+ (*Disposition)->Mask = Mask;
+ (*Disposition)->Function = Function;
+ (*Disposition)->Argument = Argument;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
}
-}
-XEN_API
-VOID
-LogDisable(
- VOID
- )
-{
- __LogDisable();
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ ReleaseHighLock(&Context->Lock, Irql);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
+
+ *Disposition = NULL;
+
+ ReleaseHighLock(&Context->Lock, Irql);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
}
-VOID
-LogTeardown(
- VOID
+extern VOID
+LogRemoveDisposition(
+ IN PLOG_DISPOSITION Disposition
)
{
- __LogDisable();
+ PLOG_CONTEXT Context = &LogContext;
+ KIRQL Irql;
+ ULONG Index;
+
+ AcquireHighLock(&Context->Lock, &Irql);
+
+ for (Index = 0; Index < LOG_MAXIMUM_DISPOSITION; Index++) {
+ if (&Context->Disposition[Index] != Disposition)
+ continue;
+
+ RtlZeroMemory(&Context->Disposition[Index], sizeof (LOG_DISPOSITION));
+ }
+
+ ReleaseHighLock(&Context->Lock, Irql);
}
-VOID
+NTSTATUS
LogInitialize(
VOID)
{
- InitializeHighLock(&LogLock);
+ PLOG_CONTEXT Context = &LogContext;
+ ULONG References;
+ NTSTATUS status;
+
+ References = InterlockedIncrement(&Context->References);
+
+ status = STATUS_OBJECTID_EXISTS;
+ if (References != 1)
+ goto fail1;
+
+ InitializeHighLock(&Context->Lock);
+
+ ASSERT(!Context->Enabled);
+
+ status = DbgSetDebugPrintCallback(LogDebugPrint, TRUE);
+ Context->Enabled = NT_SUCCESS(status) ? TRUE : FALSE;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
- __LogEnable();
+ return status;
}
#ifndef _XEN_LOG_H
#define _XEN_LOG_H
-#define __MODULE__ "XEN"
+#include <xen.h>
-#include <ntddk.h>
-#include <stdarg.h>
+typedef struct _LOG_DISPOSITION LOG_DISPOSITION, *PLOG_DISPOSITION;
-#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__)
+extern NTSTATUS
+LogAddDisposition(
+ IN LOG_LEVEL Mask,
+ IN VOID (*Function)(PVOID, PCHAR, ULONG),
+ IN PVOID Argument OPTIONAL,
+ OUT PLOG_DISPOSITION *Disposition
+ );
extern VOID
+LogRemoveDisposition(
+ IN PLOG_DISPOSITION Disposition
+ );
+
+extern NTSTATUS
LogInitialize(
- VOID);
+ VOID
+ );
extern VOID
LogTeardown(
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE LONG_PTR
* SUCH DAMAGE.
*/
-#define XEN_API __declspec(dllexport)
+#define XEN_API __declspec(dllexport)
#include <ntddk.h>
#include <ntstrsafe.h>
#include <aux_klib.h>
-#include <xen.h>
#include <util.h>
#include "high.h"
#include "module.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define MODULE_TAG 'UDOM'
CHAR Name[AUX_KLIB_MODULE_PATH_LEN];
} MODULE, *PMODULE;
-LIST_ENTRY ModuleList;
-PLIST_ENTRY ModuleCursor = &ModuleList;
-HIGH_LOCK ModuleLock;
+typedef struct _MODULE_CONTEXT {
+ LONG References;
+ LIST_ENTRY List;
+ PLIST_ENTRY Cursor;
+ HIGH_LOCK Lock;
+} MODULE_CONTEXT, *PMODULE_CONTEXT;
+
+static MODULE_CONTEXT ModuleContext;
static FORCEINLINE PVOID
__ModuleAllocate(
static FORCEINLINE VOID
__ModuleAudit(
- VOID
+ IN PMODULE_CONTEXT Context
)
{
- if (!IsListEmpty(&ModuleList)) {
+ if (!IsListEmpty(&Context->List)) {
PLIST_ENTRY ListEntry;
BOOLEAN FoundCursor;
FoundCursor = FALSE;
- for (ListEntry = ModuleList.Flink;
- ListEntry != &ModuleList;
+ for (ListEntry = Context->List.Flink;
+ ListEntry != &Context->List;
ListEntry = ListEntry->Flink) {
PMODULE Module;
- if (ListEntry == ModuleCursor)
+ if (ListEntry == Context->Cursor)
FoundCursor = TRUE;
Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
ASSERT(Module->Start < Module->End);
- if (ListEntry->Flink != &ModuleList) {
+ if (ListEntry->Flink != &Context->List) {
PMODULE Next;
Next = CONTAINING_RECORD(ListEntry->Flink, MODULE, ListEntry);
static FORCEINLINE VOID
__ModuleSearchForwards(
- IN ULONG_PTR Address
+ IN PMODULE_CONTEXT Context,
+ IN ULONG_PTR Address
)
{
- while (ModuleCursor != &ModuleList) {
+ while (Context->Cursor != &Context->List) {
PMODULE Module;
- Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+ Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
if (Address <= Module->End)
break;
- ModuleCursor = ModuleCursor->Flink;
+ Context->Cursor = Context->Cursor->Flink;
}
}
static FORCEINLINE VOID
__ModuleSearchBackwards(
- IN ULONG_PTR Address
+ IN PMODULE_CONTEXT Context,
+ IN ULONG_PTR Address
)
{
- while (ModuleCursor != &ModuleList) {
+ while (Context->Cursor != &Context->List) {
PMODULE Module;
- Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+ Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
if (Address >= Module->Start)
break;
- ModuleCursor = ModuleCursor->Blink;
+ Context->Cursor = Context->Cursor->Blink;
}
}
static FORCEINLINE NTSTATUS
__ModuleAdd(
+ IN PMODULE_CONTEXT Context,
IN PCHAR Name,
IN ULONG_PTR Start,
IN ULONG_PTR Size
InitializeListHead(&List);
- AcquireHighLock(&ModuleLock, &Irql);
+ AcquireHighLock(&Context->Lock, &Irql);
again:
After = TRUE;
- if (ModuleCursor == &ModuleList) {
- ASSERT(IsListEmpty(&ModuleList));
+ if (Context->Cursor == &Context->List) {
+ ASSERT(IsListEmpty(&Context->List));
goto done;
}
- Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+ Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
if (New->Start > Module->End) {
- __ModuleSearchForwards(New->Start);
+ __ModuleSearchForwards(Context, New->Start);
After = FALSE;
- if (ModuleCursor == &ModuleList) // End of list
+ if (Context->Cursor == &Context->List) // End of list
goto done;
- Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+ Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
if (New->End >= Module->Start) { // Overlap
- PLIST_ENTRY Cursor = ModuleCursor->Blink;
+ PLIST_ENTRY Cursor = Context->Cursor->Blink;
- RemoveEntryList(ModuleCursor);
+ RemoveEntryList(Context->Cursor);
InsertTailList(&List, &Module->ListEntry);
- ModuleCursor = Cursor;
+ Context->Cursor = Cursor;
goto again;
}
} else if (New->End < Module->Start) {
- __ModuleSearchBackwards(New->End);
+ __ModuleSearchBackwards(Context, New->End);
After = TRUE;
- if (ModuleCursor == &ModuleList) // Start of list
+ if (Context->Cursor == &Context->List) // Start of list
goto done;
- Module = CONTAINING_RECORD(ModuleCursor, MODULE, ListEntry);
+ Module = CONTAINING_RECORD(Context->Cursor, MODULE, ListEntry);
if (New->Start <= Module->End) { // Overlap
- PLIST_ENTRY Cursor = ModuleCursor->Flink;
+ PLIST_ENTRY Cursor = Context->Cursor->Flink;
- RemoveEntryList(ModuleCursor);
+ RemoveEntryList(Context->Cursor);
InsertTailList(&List, &Module->ListEntry);
- ModuleCursor = Cursor;
+ Context->Cursor = Cursor;
goto again;
}
} else {
PLIST_ENTRY Cursor;
- Cursor = (ModuleCursor->Flink != &ModuleList) ?
- ModuleCursor->Flink :
- ModuleCursor->Blink;
+ Cursor = (Context->Cursor->Flink != &Context->List) ?
+ Context->Cursor->Flink :
+ Context->Cursor->Blink;
- RemoveEntryList(ModuleCursor);
+ RemoveEntryList(Context->Cursor);
InsertTailList(&List, &Module->ListEntry);
- ModuleCursor = Cursor;
+ Context->Cursor = Cursor;
goto again;
}
done:
if (After)
- INSERT_AFTER(ModuleCursor, &New->ListEntry);
+ INSERT_AFTER(Context->Cursor, &New->ListEntry);
else
- INSERT_BEFORE(ModuleCursor, &New->ListEntry);
+ INSERT_BEFORE(Context->Cursor, &New->ListEntry);
- ModuleCursor = &New->ListEntry;
+ Context->Cursor = &New->ListEntry;
- ReleaseHighLock(&ModuleLock, Irql);
+ ReleaseHighLock(&Context->Lock, Irql);
while (!IsListEmpty(&List)) {
PLIST_ENTRY ListEntry;
__ModuleFree(Module);
}
- __ModuleAudit();
+ __ModuleAudit(Context);
return STATUS_SUCCESS;
IN PIMAGE_INFO ImageInfo
)
{
+ PMODULE_CONTEXT Context = &ModuleContext;
ANSI_STRING Ansi;
PCHAR Buffer;
PCHAR Name;
Name = strrchr((const CHAR *)Buffer, '\\');
Name = (Name == NULL) ? Buffer : (Name + 1);
- status = __ModuleAdd(Name,
+ status = __ModuleAdd(Context,
+ Name,
(ULONG_PTR)ImageInfo->ImageBase,
(ULONG_PTR)ImageInfo->ImageSize);
if (!NT_SUCCESS(status))
OUT PULONG_PTR Offset
)
{
+ PMODULE_CONTEXT Context = &ModuleContext;
PLIST_ENTRY ListEntry;
KIRQL Irql;
*Name = NULL;
*Offset = 0;
- AcquireHighLock(&ModuleLock, &Irql);
+ AcquireHighLock(&Context->Lock, &Irql);
- for (ListEntry = ModuleList.Flink;
- ListEntry != &ModuleList;
+ for (ListEntry = Context->List.Flink;
+ ListEntry != &Context->List;
ListEntry = ListEntry->Flink) {
PMODULE Module;
}
}
- ReleaseHighLock(&ModuleLock, Irql);
+ ReleaseHighLock(&Context->Lock, Irql);
}
VOID
VOID
)
{
+ PMODULE_CONTEXT Context = &ModuleContext;
+
(VOID) PsRemoveLoadImageNotifyRoutine(ModuleLoad);
- while (!IsListEmpty(&ModuleList)) {
+ Context->Cursor = NULL;
+
+ while (!IsListEmpty(&Context->List)) {
PLIST_ENTRY ListEntry;
PMODULE Module;
- ListEntry = RemoveHeadList(&ModuleList);
- ASSERT(ListEntry != &ModuleList);
+ ListEntry = RemoveHeadList(&Context->List);
+ ASSERT(ListEntry != &Context->List);
Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
__ModuleFree(Module);
}
- RtlZeroMemory(&ModuleList, sizeof (LIST_ENTRY));
+ RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY));
+
+ RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK));
+
+ (VOID) InterlockedDecrement(&Context->References);
+
+ ASSERT(IsZeroMemory(Context, sizeof (MODULE_CONTEXT)));
}
NTSTATUS
ModuleInitialize(
VOID)
{
+ PMODULE_CONTEXT Context = &ModuleContext;
+ ULONG References;
ULONG BufferSize;
ULONG Count;
PAUX_MODULE_EXTENDED_INFO QueryInfo;
ULONG Index;
NTSTATUS status;
- InitializeHighLock(&ModuleLock);
+ References = InterlockedIncrement(&Context->References);
+
+ status = STATUS_OBJECTID_EXISTS;
+ if (References != 1)
+ goto fail1;
+
+ InitializeHighLock(&Context->Lock);
(VOID) AuxKlibInitialize();
sizeof (AUX_MODULE_EXTENDED_INFO),
NULL);
if (!NT_SUCCESS(status))
- goto fail1;
+ goto fail2;
status = STATUS_UNSUCCESSFUL;
if (BufferSize == 0)
- goto fail2;
+ goto fail3;
Count = BufferSize / sizeof (AUX_MODULE_EXTENDED_INFO);
QueryInfo = __ModuleAllocate(sizeof (AUX_MODULE_EXTENDED_INFO) * Count);
status = STATUS_NO_MEMORY;
if (QueryInfo == NULL)
- goto fail3;
+ goto fail4;
status = AuxKlibQueryModuleInformation(&BufferSize,
sizeof (AUX_MODULE_EXTENDED_INFO),
QueryInfo);
if (!NT_SUCCESS(status))
- goto fail4;
+ goto fail5;
- InitializeListHead(&ModuleList);
+ InitializeListHead(&Context->List);
+ Context->Cursor = &Context->List;
for (Index = 0; Index < Count; Index++) {
PCHAR Name;
Name = strrchr((const CHAR *)QueryInfo[Index].FullPathName, '\\');
Name = (Name == NULL) ? (PCHAR)QueryInfo[Index].FullPathName : (Name + 1);
- status = __ModuleAdd(Name,
+ status = __ModuleAdd(Context,
+ Name,
(ULONG_PTR)QueryInfo[Index].BasicInfo.ImageBase,
(ULONG_PTR)QueryInfo[Index].ImageSize);
if (!NT_SUCCESS(status))
- goto fail5;
+ goto fail6;
}
status = PsSetLoadImageNotifyRoutine(ModuleLoad);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail7;
__ModuleFree(QueryInfo);
- __ModuleAudit();
-
return STATUS_SUCCESS;
+fail7:
+ Error("fail7\n");
+
fail6:
Error("fail6\n");
-fail5:
- Error("fail5\n");
-
- while (!IsListEmpty(&ModuleList)) {
+ while (!IsListEmpty(&Context->List)) {
PLIST_ENTRY ListEntry;
PMODULE Module;
- ListEntry = RemoveHeadList(&ModuleList);
- ASSERT(ListEntry != &ModuleList);
+ ListEntry = RemoveHeadList(&Context->List);
+ ASSERT(ListEntry != &Context->List);
Module = CONTAINING_RECORD(ListEntry, MODULE, ListEntry);
__ModuleFree(Module);
}
- RtlZeroMemory(&ModuleList, sizeof (LIST_ENTRY));
+ RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY));
-fail4:
- Error("fail4\n");
+fail5:
+ Error("fail5\n");
__ModuleFree(QueryInfo);
+fail4:
+ Error("fail4\n");
+
fail3:
Error("fail3\n");
fail1:
Error("fail1 (%08x)\n", status);
+ (VOID) InterlockedDecrement(&Context->References);
+
+ ASSERT(IsZeroMemory(Context, sizeof (MODULE_CONTEXT)));
+
return status;
}
#include <xen.h>
#include "process.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
+typedef struct _PROCESS_CONTEXT {
+ LONG References;
+} PROCESS_CONTEXT, *PPROCESS_CONTEXT;
+
+static PROCESS_CONTEXT ProcessContext;
+
static VOID
ProcessNotify(
- IN HANDLE ParentId,
- IN HANDLE ProcessId,
- IN BOOLEAN Create
+ IN HANDLE ParentId,
+ IN HANDLE ProcessId,
+ IN BOOLEAN Create
)
{
- static LONG HAP = -1;
- KIRQL Irql;
- PHYSICAL_ADDRESS Address;
- NTSTATUS status;
+ KIRQL Irql;
+ PHYSICAL_ADDRESS Address;
UNREFERENCED_PARAMETER(ParentId);
UNREFERENCED_PARAMETER(ProcessId);
if (Create)
return;
- if (HAP > 0) // Hardware Assisted Paging
- return;
-
// Process destruction callbacks occur within the context of the
// dying process so just read the current CR3 and notify Xen that
// it's about to cease pointing at a page table hierarchy.
- // If the hypercall fails with EINVAL the either we're not an HVM
- // domain, which would be pretty miraculous, or HAP is turned on
- // in which case we need not tell Xen about CR3 invalidation.
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
- Address.QuadPart = __readcr3();
- status = HvmPagetableDying(Address);
- if (!NT_SUCCESS(status) && HAP < 0) {
- HAP = (status == STATUS_INVALID_PARAMETER) ? 1 : 0;
-
- Info("PAGING MODE: %s\n", (HAP > 0) ? "HAP" : "Shadow");
- }
+ Address.QuadPart = __readcr3();
+ (VOID)HvmPagetableDying(Address);
KeLowerIrql(Irql);
}
VOID
)
{
+ PPROCESS_CONTEXT Context = &ProcessContext;
+
(VOID) PsSetCreateProcessNotifyRoutine(ProcessNotify, TRUE);
+
+ (VOID) InterlockedDecrement(&Context->References);
+
+ ASSERT(IsZeroMemory(Context, sizeof (PROCESS_CONTEXT)));
}
NTSTATUS
ProcessInitialize(
- VOID)
+ VOID
+ )
{
- NTSTATUS status;
+ PPROCESS_CONTEXT Context = &ProcessContext;
+ ULONG References;
+ NTSTATUS status;
+
+ References = InterlockedIncrement(&Context->References);
+
+ status = STATUS_OBJECTID_EXISTS;
+ if (References != 1)
+ goto fail1;
status = PsSetCreateProcessNotifyRoutine(ProcessNotify, FALSE);
if (!NT_SUCCESS(status))
- goto fail1;
+ goto fail2;
return STATUS_SUCCESS;
+fail2:
+ Error("fail2\n");
+
fail1:
Error("fail1 (%08x)\n", status);
+ (VOID) InterlockedDecrement(&Context->References);
+
+ ASSERT(IsZeroMemory(Context, sizeof (PROCESS_CONTEXT)));
+
return status;
}
#include <xen.h>
#include "hypercall.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE LONG_PTR
#include <util.h>
#include "system.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE const CHAR *
+++ /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 XEN_API __declspec(dllexport)
-
-#include <ntddk.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <xen.h>
-#include <util.h>
-
-#include <binding.h>
-
-#include "unplug.h"
-#include "log.h"
-#include "assert.h"
-
-typedef struct _UNPLUG_CONTEXT {
- LONG References;
- KSPIN_LOCK Lock;
-} UNPLUG_CONTEXT, *PUNPLUG_CONTEXT;
-
-UNPLUG_CONTEXT UnplugContext;
-
-static PVOID Port10 = ((PVOID)(ULONG_PTR)0x10);
-static PVOID Port11 = ((PVOID)(ULONG_PTR)0x11);
-static PVOID Port12 = ((PVOID)(ULONG_PTR)0x12);
-static PVOID Port13 = ((PVOID)(ULONG_PTR)0x13);
-
-typedef enum _UNPLUG_TYPE {
- UNPLUG_TYPE_INVALID = 0,
- UNPLUG_TYPE_IDE,
- UNPLUG_TYPE_NIC,
- UNPLUG_TYPE_COUNT
-} UNPLUG_TYPE, *PUNPLUG_TYPE;
-
-#define MAXIMUM_UNPLUG_INDEX ((1 << (sizeof (UCHAR) * 8)) - 1)
-
-static FORCEINLINE USHORT
-__UnplugReadMagic(
- VOID
- )
-{
- return READ_PORT_USHORT(Port10);
-}
-
-#define UNPLUG_MAGIC 0x49D2
-
-static FORCEINLINE UCHAR
-__UnplugReadVersion(
- VOID
- )
-{
- return READ_PORT_UCHAR(Port12);
-}
-
-static FORCEINLINE VOID
-__UnplugWriteVersion(
- IN UCHAR Version
- )
-{
- // Careful here: we must speculatively set the version 2 unplug type to
- // an invalid value. This is because, if the unplug protocol is already set
- // to version 2 then writing the version will actually perform an unplug.
- // However, if the unplug type is invalid nothing will actually disappear!
-
- WRITE_PORT_UCHAR(Port11, (UCHAR)UNPLUG_TYPE_INVALID);
- WRITE_PORT_UCHAR(Port13, Version);
-}
-
-static FORCEINLINE UCHAR
-__UnplugGetVersion(
- VOID
- )
-{
- UCHAR Version;
-
- __UnplugWriteVersion(2);
- Version = __UnplugReadVersion();
-
- return Version;
-}
-
-#define UNPLUG_PRODUCT_ID 3
-
-static FORCEINLINE VOID
-__UnplugWriteProductId(
- IN USHORT Id
- )
-{
- WRITE_PORT_USHORT(Port12, Id);
-}
-
-#define UNPLUG_BUILD_NUMBER ((PCI_DEVICE_ID << 8) | PCI_REVISION)
-
-static FORCEINLINE VOID
-__UnplugWriteBuildNumber(
- IN ULONG BuildNumber
- )
-{
- WRITE_PORT_ULONG(Port10, BuildNumber);
-}
-
-static FORCEINLINE VOID
-__UnplugWriteUnplugCommand(
- IN UCHAR Type,
- IN UCHAR Index
- )
-{
- WRITE_PORT_UCHAR(Port11, Type);
- WRITE_PORT_UCHAR(Port13, Index);
-}
-
-static FORCEINLINE NTSTATUS
-__UnplugPrepare(
- VOID
- )
-{
- USHORT Magic;
- UCHAR Version;
- NTSTATUS status;
-
- Magic = __UnplugReadMagic();
-
- status = STATUS_NO_SUCH_DEVICE;
- if (Magic != UNPLUG_MAGIC)
- goto fail1;
-
- Version = __UnplugGetVersion();
-
- // We only support version 2 onwards
-
- status = STATUS_NOT_SUPPORTED;
- if (Version < 2)
- goto fail2;
-
- // Version 1 of the unplug protocol onwards allows for blacklisting of
- // drivers. This is done by modifying the returned magic number if the
- // drivers should not be used.
-
- __UnplugWriteProductId(UNPLUG_PRODUCT_ID);
- __UnplugWriteBuildNumber(UNPLUG_BUILD_NUMBER);
-
- Magic = __UnplugReadMagic();
-
- status = STATUS_INVALID_PARAMETER;
- if (Magic != UNPLUG_MAGIC)
- goto fail3;
-
- return STATUS_SUCCESS;
-
-fail3:
- Error("fail3\n");
-
-fail2:
- Error("fail2\n");
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-XEN_API
-NTSTATUS
-UnplugReference(
- VOID
- )
-{
- ULONG References;
- KIRQL Irql;
- NTSTATUS status;
-
- Trace("====>\n");
-
- KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
- References = UnplugContext.References++;
-
- if (References == 0) {
- status = __UnplugPrepare();
- if (!NT_SUCCESS(status))
- goto fail1;
- }
-
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
- Trace("<==== (%u)\n", References);
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- ASSERT(UnplugContext.References != 0);
- --UnplugContext.References;
-
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
- return status;
-}
-
-static BOOLEAN UnplugEntry[UNPLUG_TYPE_COUNT][MAXIMUM_UNPLUG_INDEX + 1];
-
-XEN_API
-VOID
-UnplugDereference(
- VOID
- )
-{
- ULONG References;
- KIRQL Irql;
-
- Trace("====>\n");
-
- KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
- References = UnplugContext.References;
-
- if (References == 0)
- goto done;
-
- --UnplugContext.References;
-
- if (References == 0)
- RtlZeroMemory(UnplugEntry, sizeof (BOOLEAN) * UNPLUG_TYPE_COUNT * (MAXIMUM_UNPLUG_INDEX + 1));
-
-done:
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
- Trace("<==== (%u)\n", References);
-}
-
-XEN_API
-NTSTATUS
-UnplugDevice(
- PCHAR Class,
- PCHAR Device
- )
-{
- KIRQL Irql;
- UNPLUG_TYPE Type;
- UCHAR Index;
- NTSTATUS status;
-
- KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
- ASSERT(UnplugContext.References != 0);
-
- Info("%s %s\n", Class, Device);
-
- status = STATUS_INVALID_PARAMETER;
- if (strcmp(Class, "VIF") == 0)
- Type = UNPLUG_TYPE_NIC;
- else if (strcmp(Class, "VBD") == 0)
- Type = UNPLUG_TYPE_IDE;
- else
- goto fail1;
-
- ASSERT3U(Type, <, UNPLUG_TYPE_COUNT);
-
- Index = (UCHAR)strtol(Device, NULL, 0);
- ASSERT3U(Index, <=, MAXIMUM_UNPLUG_INDEX);
-
- if (!UnplugEntry[Type][Index]) {
- UnplugEntry[Type][Index] = TRUE;
- __UnplugWriteUnplugCommand(Type, Index);
- }
-
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-
- return status;
-}
-
-XEN_API
-VOID
-UnplugReplay(
- VOID
- )
-{
- KIRQL Irql;
- UNPLUG_TYPE Type;
- ULONG Index;
- NTSTATUS status;
-
- KeAcquireSpinLock(&UnplugContext.Lock, &Irql);
-
- if (UnplugContext.References == 0)
- goto done;
-
- status = __UnplugPrepare();
- ASSERT(NT_SUCCESS(status));
-
- for (Type = 0; Type < UNPLUG_TYPE_COUNT; Type++) {
- if (Type == UNPLUG_TYPE_INVALID)
- continue;
-
- for (Index = 0; Index <= MAXIMUM_UNPLUG_INDEX; Index++) {
- if (UnplugEntry[Type][Index])
- __UnplugWriteUnplugCommand(Type, (UCHAR)Index);
- }
- }
-
-done:
- KeReleaseSpinLock(&UnplugContext.Lock, Irql);
-}
-
-VOID
-UnplugInitialize(
- VOID
- )
-{
- ASSERT(IsZeroMemory(&UnplugContext, sizeof (UNPLUG_CONTEXT)));
-
- KeInitializeSpinLock(&UnplugContext.Lock);
-}
-
-VOID
-UnplugTeardown(
- VOID
- )
-{
- RtlZeroMemory(&UnplugContext.Lock, sizeof (KSPIN_LOCK));
-
- ASSERT(IsZeroMemory(&UnplugContext, sizeof (UNPLUG_CONTEXT)));
-}
+++ /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 _XEN_UNPLUG_H
-#define _XEN_UNPLUG_H
-
-#include <ntddk.h>
-#include <xen.h>
-
-extern VOID
-UnplugInitialize(
- VOID
- );
-
-extern VOID
-UnplugTeardown(
- VOID
- );
-
-#endif // _XEN_UNPLUG_H
%Citrix%=Citrix,NT$ARCH$
[Citrix.NT$ARCH$]
-%XenBusDesc%=XenBus_Inst,PCI\VEN_@PCI_VENDOR_ID@&DEV_@PCI_DEVICE_ID@&SUBSYS_@PCI_DEVICE_ID@@PCI_VENDOR_ID@&REV_@PCI_REVISION@
+; DisplayName Section DeviceID
+; ----------- ------- --------
+
+%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_C000&SUBSYS_C0005853&REV_01
+%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_0002
+%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_0001
[XenBus_Inst]
CopyFiles=XenBus_Copyfiles
[XenFilt_Parameters]
HKR,"Parameters",,0x00000010
-
HKR,"Parameters","FilterDevices",0x00010000,"ACPI\PNP0A03","PCIIDE\IDEChannel"
-HKR,"Parameters","ACPI\PNP0A03",0x00010000,"VIF","VBD"
-
-HKR,"Aliases",,0x00000010
-
-HKR,"Aliases\VIF",,0x00000010
-
-HKR,"Aliases\VIF","0",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#20"
-HKR,"Aliases\VIF","1",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#28"
-HKR,"Aliases\VIF","2",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#30"
-HKR,"Aliases\VIF","3",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#38"
-HKR,"Aliases\VIF","4",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#40"
-HKR,"Aliases\VIF","5",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#48"
-HKR,"Aliases\VIF","6",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#50"
-HKR,"Aliases\VIF","7",0x00000000,"PCI\VEN_10EC&DEV_8139&SUBSYS_00015853&REV_20#58"
-
-HKR,"Aliases\VBD",,0x00000010
-
-HKR,"Aliases\VBD","0",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#0.0.0"
-HKR,"Aliases\VBD","1",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#0.1.0"
-HKR,"Aliases\VBD","2",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#1.0.0"
-HKR,"Aliases\VBD","3",0x00000000,"IDE\DiskQEMU_HARDDISK___________________________0.10.2__#1.1.0"
[XenBus_Inst.CoInstallers]
CopyFiles=CoInst_CopyFiles
[Strings]
Citrix="Citrix Systems Inc."
-DiskDesc="Citrix Tools for Virtual Machines"
-XenBusDesc="Citrix PV Bus"
-XenFiltDesc="Citrix Bus Filter"
+DiskDesc="XenServer Tools for Virtual Machines"
+XenBusDesc="XenServer PV Bus"
+XenFiltDesc="XenServer Bus Filter"
SERVICE_BOOT_START=0x0
SERVICE_SYSTEM_START=0x1
+++ /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 _XENBUS_ASSERT_H
-#define _XENBUS_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); \
- __analysis_assume(_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 // _XENBUS_ASSERT_H
-
#include "mutex.h"
#include "balloon.h"
#include "range_set.h"
+#include "dbg_print.h"
#include "assert.h"
-#include "log.h"
#define BALLOON_AUDIT DBG
{
PKEVENT LowMemoryEvent;
HANDLE LowMemoryHandle;
- XENBUS_MUTEX Mutex;
+ MUTEX Mutex;
ULONGLONG Size;
PXENBUS_RANGE_SET RangeSet;
MDL Mdl;
fail3:
Error("fail3\n");
- RtlZeroMemory(&(*Balloon)->Mutex, sizeof (XENBUS_MUTEX));
+ RtlZeroMemory(&(*Balloon)->Mutex, sizeof (MUTEX));
fail2:
Error("fail2\n");
Balloon->LowMemoryHandle = NULL;
Balloon->LowMemoryEvent = NULL;
- RtlZeroMemory(&Balloon->Mutex, sizeof (XENBUS_MUTEX));
+ RtlZeroMemory(&Balloon->Mutex, sizeof (MUTEX));
RangeSetTeardown(Balloon->RangeSet);
Balloon->RangeSet = NULL;
#include "dma.h"
#include "fdo.h"
#include "pdo.h"
-#include "log.h"
+#include "registry.h"
#include "sync.h"
+#include "dbg_print.h"
#include "assert.h"
typedef struct _XENBUS_BUS_CONTEXT {
LONG References;
PXENBUS_PDO Pdo;
+ ULONG InterceptDmaAdapter;
} XENBUS_BUS_CONTEXT, *PXENBUS_BUS_CONTEXT;
#define BUS_TAG 'SUB'
PXENBUS_BUS_CONTEXT Context = _Context;
XENBUS_DMA_ADAPTER_TYPE Type;
- if (DriverParameters.InterceptDmaAdapter != 0) {
+ if (Context->InterceptDmaAdapter != 0) {
RTL_OSVERSIONINFOEXW VersionInformation;
RtlGetVersion((PRTL_OSVERSIONINFOW)&VersionInformation);
)
{
PXENBUS_BUS_CONTEXT Context;
+ HANDLE ParametersKey;
NTSTATUS status;
Trace("====>\n");
Context->Pdo = Pdo;
+ ParametersKey = DriverGetParametersKey();
+
+ Context->InterceptDmaAdapter = 0;
+
+ if (ParametersKey != NULL) {
+ ULONG InterceptDmaAdapter;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "InterceptDmaAdapter",
+ &InterceptDmaAdapter);
+ if (NT_SUCCESS(status))
+ Context->InterceptDmaAdapter = InterceptDmaAdapter;
+ }
+
Interface->Size = sizeof (BUS_INTERFACE_STANDARD);
Interface->Version = 1;
Interface->Context = Context;
#include "high.h"
#include "debug.h"
#include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define MAXIMUM_PREFIX_LENGTH 32
UNREFERENCED_PARAMETER(Context);
- LogQemuPrintf("%s: ", Callback->Prefix);
+ LogPrintf(LOG_LEVEL_INFO,
+ "%s: ",
+ Callback->Prefix);
va_start(Arguments, Format);
- LogQemuVPrintf(Format, Arguments);
+ LogVPrintf(LOG_LEVEL_INFO,
+ Format,
+ Arguments);
va_end(Arguments);
}
ModuleLookup((ULONG_PTR)Callback->Caller, &Name, &Offset);
if (Name != NULL) {
- LogQemuPrintf("XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %s + %p\n",
- Callback->Function,
- Callback->Prefix,
- Name,
- Offset);
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %s + %p\n",
+ Callback->Function,
+ Callback->Prefix,
+ Name,
+ Offset);
} else {
- LogQemuPrintf("XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %p\n",
- Callback->Function,
- Callback->Prefix,
- Callback->Caller);
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN|DEBUG: SKIPPING %p PREFIX '%s' REGISTERED BY %p\n",
+ Callback->Function,
+ Callback->Prefix,
+ Callback->Caller);
}
} else {
- LogQemuPrintf("XEN|DEBUG: ====> (%s + %p)\n", Name, Offset);
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN|DEBUG: ====> (%s + %p)\n",
+ Name,
+ Offset);
Callback->Function(Callback->Argument, Crashing);
- LogQemuPrintf("XEN|DEBUG: <==== (%s + %p)\n", Name, Offset);
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN|DEBUG: <==== (%s + %p)\n",
+ Name,
+ Offset);
}
}
}
#include "dma.h"
#include "fdo.h"
#include "pdo.h"
-#include "log.h"
-#include "sync.h"
+#include "dbg_print.h"
#include "assert.h"
#pragma warning(push)
* SUCH DAMAGE.
*/
-//
-// This driver responds to the following system start options:
-// (These can be set by bcdedit /set loadoptions <string>).
-//
-// /XEN:BALLOON=OFF
-//
-// The system balloon defaults to ON and is adjusted via the
-// xenstore 'memory/static-max' and 'memory/target' values. If
-// this option is present those values are ignored and the
-// balloon remains inactive.
-//
-
#include <ntddk.h>
#include <util.h>
#include "fdo.h"
#include "pdo.h"
#include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#include "version.h"
-extern const CHAR *XenVersion;
-extern const CHAR *XenPciVersion;
-
extern PULONG InitSafeBootMode;
-PDRIVER_OBJECT DriverObject;
+typedef struct _XENBUS_DRIVER {
+ PDRIVER_OBJECT DriverObject;
+ HANDLE ParametersKey;
+} XENBUS_DRIVER, *PXENBUS_DRIVER;
+
+static XENBUS_DRIVER Driver;
+
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ Driver.DriverObject = DriverObject;
+}
-HANDLE DriverServiceKey;
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+ VOID
+ )
+{
+ return Driver.DriverObject;
+}
-XENBUS_PARAMETERS DriverParameters;
+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;
- Trace("====>\n");
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
- Info("%s (%s)\n",
- MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
- DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ Trace("====>\n");
if (*InitSafeBootMode > 0)
goto done;
- RegistryFreeSzValue(DriverParameters.SyntheticClasses);
- RegistryFreeSzValue(DriverParameters.SupportedClasses);
-
- RegistryCloseKey(DriverServiceKey);
+ ParametersKey = __DriverGetParametersKey();
+ if (ParametersKey != NULL) {
+ RegistryCloseKey(ParametersKey);
+ __DriverSetParametersKey(NULL);
+ }
RegistryTeardown();
done:
- DriverObject = NULL;
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENBUS_DRIVER)));
Trace("<====\n");
}
+__drv_functionClass(IO_COMPLE7TION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+DriverQueryIdCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PKEVENT Event = Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static FORCEINLINE NTSTATUS
+__DriverQueryId(
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN BUS_QUERY_ID_TYPE IdType,
+ OUT PVOID *Information
+ )
+{
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ KEVENT Event;
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ DeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
+
+ Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ if (Irp == NULL)
+ goto fail1;
+
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+
+ StackLocation->MajorFunction = IRP_MJ_PNP;
+ StackLocation->MinorFunction = IRP_MN_QUERY_ID;
+ StackLocation->Flags = 0;
+ StackLocation->Parameters.QueryId.IdType = IdType;
+ StackLocation->DeviceObject = DeviceObject;
+ StackLocation->FileObject = NULL;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ IoSetCompletionRoutine(Irp,
+ DriverQueryIdCompletion,
+ &Event,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ // Default completion status
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(DeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = Irp->IoStatus.Status;
+ } else {
+ ASSERT3U(status, ==, Irp->IoStatus.Status);
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ *Information = (PVOID)Irp->IoStatus.Information;
+
+ IoFreeIrp(Irp);
+ ObDereferenceObject(DeviceObject);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
+
+ IoFreeIrp(Irp);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ ObDereferenceObject(DeviceObject);
+
+ return status;
+}
+
DRIVER_ADD_DEVICE AddDevice;
NTSTATUS
#pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
AddDevice(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject
)
{
+ HANDLE ParametersKey;
+ PANSI_STRING ActiveDeviceInstance;
+ BOOLEAN Active;
+ PWCHAR DeviceID;
+ PWCHAR InstanceID;
+ UNICODE_STRING Unicode;
+ ULONG Length;
NTSTATUS status;
- ASSERT3P(_DriverObject, ==, DriverObject);
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
- status = FdoCreate(DeviceObject);
+ ParametersKey = __DriverGetParametersKey();
+
+ ActiveDeviceInstance = NULL;
+ if (ParametersKey != NULL) {
+ status = RegistryQuerySzValue(ParametersKey,
+ "ActiveDeviceInstance",
+ &ActiveDeviceInstance);
+ ASSERT(IMPLY(!NT_SUCCESS(status), ActiveDeviceInstance == NULL));
+ } else {
+ ActiveDeviceInstance = NULL;
+ }
+
+ Active = FALSE;
+
+ DeviceID = NULL;
+ InstanceID = NULL;
+
+ RtlZeroMemory(&Unicode, sizeof (UNICODE_STRING));
+
+ if (ActiveDeviceInstance == NULL)
+ goto done;
+
+ status = __DriverQueryId(DeviceObject, BusQueryDeviceID, &DeviceID);
if (!NT_SUCCESS(status))
goto fail1;
+ status = __DriverQueryId(DeviceObject, BusQueryInstanceID, &InstanceID);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, ActiveDeviceInstance, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ Length = (ULONG)wcslen(DeviceID);
+ if (_wcsnicmp(Unicode.Buffer,
+ DeviceID,
+ Length) != 0)
+ goto done;
+
+ Length = (ULONG)wcslen(InstanceID);
+ if (_wcsnicmp(Unicode.Buffer + (Unicode.Length / sizeof (WCHAR)) - Length,
+ InstanceID,
+ Length) != 0)
+ goto done;
+
+ Active = TRUE;
+
+ RegistryFreeSzValue(ActiveDeviceInstance);
+
+done:
+ if (Unicode.Buffer != NULL)
+ RtlFreeUnicodeString(&Unicode);
+
+ if (InstanceID != NULL)
+ ExFreePool(InstanceID);
+
+ if (DeviceID != NULL)
+ ExFreePool(DeviceID);
+
+ status = FdoCreate(DeviceObject, Active);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
return STATUS_SUCCESS;
+fail3:
+ Error("fail3\n");
+
+ if (InstanceID != NULL)
+ ExFreePool(InstanceID);
+
+fail2:
+ Error("fail2\n");
+
+ if (DeviceID != NULL)
+ ExFreePool(DeviceID);
+
fail1:
+ RegistryFreeSzValue(ActiveDeviceInstance);
+
Error("fail1 (%08x)\n", status);
return status;
NTSTATUS
DriverEntry(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
+ HANDLE ServiceKey;
HANDLE ParametersKey;
- PANSI_STRING Options;
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;
+
+ LogPrintf(LOG_LEVEL_INFO,
+ "XENBUS %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 = RegistryOpenServiceKey(KEY_READ, &DriverServiceKey);
+ status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
if (!NT_SUCCESS(status))
goto fail2;
- DriverParameters.SupportedClasses = NULL;
- DriverParameters.SyntheticClasses = NULL;
- DriverParameters.CreatePDOs = 1;
- DriverParameters.InterceptDmaAdapter = 0;
-
- status = RegistryOpenSubKey(DriverServiceKey, "Parameters", KEY_READ, &ParametersKey);
- if (NT_SUCCESS(status)) {
- PANSI_STRING SupportedClasses;
- PANSI_STRING SyntheticClasses;
- ULONG CreatePDOs;
- ULONG InterceptDmaAdapter;
+ status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
+ if (NT_SUCCESS(status))
+ __DriverSetParametersKey(ParametersKey);
- status = RegistryQuerySzValue(ParametersKey,
- "SupportedClasses",
- &SupportedClasses);
- if (NT_SUCCESS(status))
- DriverParameters.SupportedClasses = SupportedClasses;
-
- status = RegistryQuerySzValue(ParametersKey,
- "SyntheticClasses",
- &SyntheticClasses);
- if (NT_SUCCESS(status))
- DriverParameters.SyntheticClasses = SyntheticClasses;
-
- status = RegistryQueryDwordValue(ParametersKey,
- "CreatePDOs",
- &CreatePDOs);
- if (NT_SUCCESS(status))
- DriverParameters.CreatePDOs = CreatePDOs;
-
- status = RegistryQueryDwordValue(ParametersKey,
- "InterceptDmaAdapter",
- &InterceptDmaAdapter);
- if (NT_SUCCESS(status))
- DriverParameters.InterceptDmaAdapter = InterceptDmaAdapter;
-
- RegistryCloseKey(ParametersKey);
- }
-
- DriverParameters.Balloon = 1;
-
- status = RegistryQuerySystemStartOptions(&Options);
- if (NT_SUCCESS(status)) {
- const CHAR Key[] = " XEN:BALLOON=";
- PCHAR Value;
-
- Trace("Options = '%Z'\n", Options);
-
- Value = strstr(Options->Buffer, Key);
- if (Value != NULL) {
- Value += sizeof (Key) - 1;
-
- if (strcmp(Value, "OFF") == 0)
- DriverParameters.Balloon = 0;
- }
-
- RegistryFreeSzValue(Options);
- }
+ RegistryCloseKey(ServiceKey);
DriverObject->DriverExtension->AddDevice = AddDevice;
fail1:
Error("fail1 (%08x)\n", status);
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENBUS_DRIVER)));
+
return status;
}
#ifndef _XENBUS_DRIVER_H
#define _XENBUS_DRIVER_H
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+ VOID
+ );
+
+extern HANDLE
+DriverGetParametersKey(
+ VOID
+ );
+
typedef struct _XENBUS_FDO XENBUS_FDO, *PXENBUS_FDO;
typedef struct _XENBUS_PDO XENBUS_PDO, *PXENBUS_PDO;
#include "pdo.h"
#include "fdo.h"
-extern PDRIVER_OBJECT DriverObject;
-
-typedef struct _XENBUS_PARAMETERS {
- PANSI_STRING SupportedClasses;
- PANSI_STRING SyntheticClasses;
- ULONG CreatePDOs;
- ULONG Balloon;
- ULONG InterceptDmaAdapter;
-} XENBUS_PARAMETERS, *PXENBUS_PARAMETERS;
-
-extern XENBUS_PARAMETERS DriverParameters;
-
#define MAX_DEVICE_ID_LEN 200
#pragma warning(push)
#include "evtchn.h"
#include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
typedef struct _EVTCHN_FIXED_PARAMETERS {
#include "sync.h"
#include "balloon.h"
#include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define FDO_TAG 'ODF'
PXENBUS_THREAD DevicePowerThread;
PIRP DevicePowerIrp;
+ CHAR VendorName[MAXNAMELEN];
+ BOOLEAN Active;
+
PXENBUS_THREAD ScanThread;
KEVENT ScanEvent;
PXENBUS_STORE_WATCH ScanWatch;
- XENBUS_MUTEX Mutex;
+ MUTEX Mutex;
ULONG References;
PXENBUS_THREAD SuspendThread;
KEVENT SuspendEvent;
NumberOfMapRegisters);
}
-static FORCEINLINE NTSTATUS
-__FdoSetName(
+static FORCEINLINE VOID
+__FdoSetVendorName(
IN PXENBUS_FDO Fdo,
- IN PWCHAR Name
+ IN USHORT DeviceID
)
{
- PXENBUS_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 PXENBUS_FDO Fdo
+ )
+{
+ return Fdo->VendorName;
+}
- return STATUS_SUCCESS;
+PCHAR
+FdoGetVendorName(
+ IN PXENBUS_FDO Fdo
+ )
+{
+ return __FdoGetVendorName(Fdo);
+}
-fail1:
- Error("fail1 (%08x)\n", status);
+static FORCEINLINE VOID
+__FdoSetName(
+ IN PXENBUS_FDO Fdo
+ )
+{
+ PXENBUS_DX Dx = Fdo->Dx;
+ NTSTATUS status;
- return status;
+ status = RtlStringCbPrintfA(Dx->Name,
+ MAXNAMELEN,
+ "%s XEN",
+ __FdoGetVendorName(Fdo));
+ ASSERT(NT_SUCCESS(status));
}
static FORCEINLINE PCHAR
return __FdoGetName(Fdo);
}
+static FORCEINLINE VOID
+__FdoSetActive(
+ IN PXENBUS_FDO Fdo,
+ IN BOOLEAN Active
+ )
+{
+ Fdo->Active = Active;
+}
+
+static FORCEINLINE BOOLEAN
+__FdoIsActive(
+ IN PXENBUS_FDO Fdo
+ )
+{
+ return Fdo->Active;
+}
+
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
NeedInvalidate = FALSE;
- if (DriverParameters.CreatePDOs == 0)
- goto done;
-
__FdoAcquireMutex(Fdo);
ListEntry = Fdo->Dx->ListEntry.Flink;
Name = PdoGetName(Pdo);
Missing = TRUE;
- // If the PDO exists in either the class list or the synthetic 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; Classes[Index].Buffer != NULL; Index++) {
PANSI_STRING Class = &Classes[Index];
+ if (Class->Length == 0)
+ continue;
+
if (strcmp(Name, Class->Buffer) == 0) {
Missing = FALSE;
Class->Length = 0; // avoid duplication
ListEntry = Next;
}
- // Check the class list from xenstore against the supported list
- for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
- PANSI_STRING Class = &Classes[Index];
- ULONG Entry;
- BOOLEAN Supported;
-
- Supported = FALSE;
-
- for (Entry = 0;
- DriverParameters.SupportedClasses != NULL && DriverParameters.SupportedClasses[Entry].Buffer != NULL;
- Entry++) {
- if (strncmp(Class->Buffer,
- DriverParameters.SupportedClasses[Entry].Buffer,
- Class->Length) == 0) {
- Supported = TRUE;
- break;
- }
- }
-
- if (!Supported)
- Class->Length = 0; // avoid creation
- }
-
// Walk the class list and create PDOs for any new classes
-
for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
PANSI_STRING Class = &Classes[Index];
__FdoReleaseMutex(Fdo);
-done:
Trace("<====\n");
return NeedInvalidate;
{
PXENBUS_FDO Fdo = Context;
PKEVENT Event;
+ HANDLE ParametersKey;
NTSTATUS status;
Trace("====>\n");
Event = ThreadGetEvent(Self);
+ ParametersKey = DriverGetParametersKey();
+
for (;;) {
PCHAR Buffer;
PANSI_STRING StoreClasses;
+ PANSI_STRING SyntheticClasses;
+ PANSI_STRING SupportedClasses;
PANSI_STRING Classes;
+ ULONG Index;
BOOLEAN NeedInvalidate;
Trace("waiting...\n");
StoreClasses = NULL;
}
- Classes = __FdoCombineAnsi(StoreClasses, DriverParameters.SyntheticClasses);
+ if (ParametersKey != NULL) {
+ status = RegistryQuerySzValue(ParametersKey,
+ "SyntheticClasses",
+ &SyntheticClasses);
+ ASSERT(IMPLY(!NT_SUCCESS(status), SyntheticClasses == NULL));
+ } else {
+ SyntheticClasses = NULL;
+ }
+
+ Classes = __FdoCombineAnsi(StoreClasses, SyntheticClasses);
if (StoreClasses != NULL)
__FdoFreeAnsi(StoreClasses);
+ if (SyntheticClasses != NULL)
+ RegistryFreeSzValue(SyntheticClasses);
+
if (Classes == NULL)
goto loop;
+ if (ParametersKey != NULL) {
+ status = RegistryQuerySzValue(ParametersKey,
+ "SupportedClasses",
+ &SupportedClasses);
+ ASSERT(IMPLY(!NT_SUCCESS(status), SyntheticClasses == NULL));
+ } else {
+ SupportedClasses = NULL;
+ }
+
+ // NULL out anything in the Classes list that not in the
+ // SupportedClasses list
+ for (Index = 0; Classes[Index].Buffer != NULL; Index++) {
+ PANSI_STRING Class = &Classes[Index];
+ ULONG Entry;
+ BOOLEAN Supported;
+
+ Supported = FALSE;
+
+ for (Entry = 0;
+ SupportedClasses != NULL && SupportedClasses[Entry].Buffer != NULL;
+ Entry++) {
+ if (strncmp(Class->Buffer,
+ SupportedClasses[Entry].Buffer,
+ Class->Length) == 0) {
+ Supported = TRUE;
+ break;
+ }
+ }
+
+ if (!Supported)
+ Class->Length = 0;
+ }
+
+ if (SupportedClasses != NULL)
+ RegistryFreeSzValue(SupportedClasses);
+
NeedInvalidate = __FdoEnumerate(Fdo, Classes);
__FdoFreeAnsi(Classes);
PXENBUS_FDO Fdo = Context;
PKEVENT Event;
BOOLEAN Active;
- static ULONGLONG Maximum; // Should never change in the lifetime of the VM
+ ULONGLONG Maximum = 0;
NTSTATUS status;
Trace("====>\n");
if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
goto loop;
+ // Only sample this if it's zero as it should never change
+ // during the lifetime of the domain.
if (Maximum == 0) {
+ ULONGLONG VideoRAM;
+
status = STORE(Read,
&Fdo->StoreInterface,
NULL,
"memory",
"static-max",
&Buffer);
- if (!NT_SUCCESS(status))
+ if (NT_SUCCESS(status)) {
+ Maximum = _strtoui64(Buffer, NULL, 10);
+ STORE(Free,
+ &Fdo->StoreInterface,
+ Buffer);
+ } else {
goto loop;
+ }
- Maximum = _strtoui64(Buffer, NULL, 10) / 4;
- STORE(Free,
- &Fdo->StoreInterface,
- Buffer);
+ status = STORE(Read,
+ &Fdo->StoreInterface,
+ NULL,
+ "memory",
+ "videoram",
+ &Buffer);
+ if (NT_SUCCESS(status)) {
+ VideoRAM = _strtoui64(Buffer, NULL, 10);
+ STORE(Free,
+ &Fdo->StoreInterface,
+ Buffer);
+ } else {
+ VideoRAM = 0;
+ }
+
+ Maximum -= VideoRAM;
+ Maximum /= 4; // We need the value in pages
}
status = STORE(Read,
IN PXENBUS_FDO Fdo
)
{
- POWER_STATE PowerState;
BOOLEAN Pending;
NTSTATUS status;
&Fdo->EvtchnInterface,
Fdo->Evtchn);
- __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
-
STORE(Acquire, &Fdo->StoreInterface);
status = STORE(Watch,
1);
}
- PowerState.DeviceState = PowerDeviceD0;
- PoSetPowerState(Fdo->Dx->DeviceObject,
- DevicePowerState,
- PowerState);
-
Trace("<====\n");
return STATUS_SUCCESS;
STORE(Release, &Fdo->StoreInterface);
- __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-
EVTCHN(Close,
&Fdo->EvtchnInterface,
Fdo->Evtchn);
IN PXENBUS_FDO Fdo
)
{
- POWER_STATE PowerState;
-
Trace("====>\n");
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
-
- PowerState.DeviceState = PowerDeviceD3;
- PoSetPowerState(Fdo->Dx->DeviceObject,
- DevicePowerState,
- PowerState);
if (Fdo->Balloon != NULL) {
(VOID) STORE(Remove,
STORE(Release, &Fdo->StoreInterface);
- __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-
EVTCHN(Close,
&Fdo->EvtchnInterface,
Fdo->Evtchn);
IN PXENBUS_FDO Fdo
)
{
+ POWER_STATE PowerState;
KIRQL Irql;
PLIST_ENTRY ListEntry;
NTSTATUS status;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
+
+ Trace("====>\n");
+
+ if (!__FdoIsActive(Fdo))
+ goto done;
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
KeLowerIrql(Irql);
+done:
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
+
+ PowerState.DeviceState = PowerDeviceD0;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
__FdoAcquireMutex(Fdo);
for (ListEntry = Fdo->Dx->ListEntry.Flink;
__FdoReleaseMutex(Fdo);
+ Trace("<====\n");
+
return STATUS_SUCCESS;
fail2:
IN PXENBUS_FDO Fdo
)
{
+ POWER_STATE PowerState;
PLIST_ENTRY ListEntry;
KIRQL Irql;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
+
+ Trace("====>\n");
__FdoAcquireMutex(Fdo);
__FdoReleaseMutex(Fdo);
+ PowerState.DeviceState = PowerDeviceD3;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
SUSPEND(Deregister,
KernelMode,
FALSE,
NULL);
+done:
+ Trace("<====\n");
}
static DECLSPEC_NOINLINE NTSTATUS
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
KeRaiseIrql(DISPATCH_LEVEL, &Irql); // Flush out any attempt to use pageable memory
status = DebugInitialize(Fdo, &Fdo->DebugInterface);
KeLowerIrql(Irql);
+done:
Trace("<====\n");
return STATUS_SUCCESS;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemSleeping3);
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
__FdoDisableInterrupt(Fdo);
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
DebugTeardown(&Fdo->DebugInterface);
+done:
Trace("<====\n");
}
StackLocation->Parameters.StartDevice.AllocatedResources,
StackLocation->Parameters.StartDevice.AllocatedResourcesTranslated);
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
status = FdoConnectInterrupt(Fdo);
if (!NT_SUCCESS(status))
goto fail2;
goto fail5;
}
+done:
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
status = FdoS4ToS3(Fdo);
if (Fdo->Balloon != NULL) {
BOOLEAN Warned;
+ ASSERT(__FdoIsActive(Fdo));
+
Warned = FALSE;
for (;;) {
}
__FdoSetDevicePnpState(Fdo, Started);
- ThreadWake(Fdo->ScanThread);
+
+ if (__FdoIsActive(Fdo))
+ ThreadWake(Fdo->ScanThread);
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
__FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
+ if (!__FdoIsActive(Fdo))
+ goto fail2;
+
if (Fdo->Balloon != NULL) {
ThreadAlert(Fdo->BalloonThread);
ThreadJoin(Fdo->BalloonThread);
{
NTSTATUS status;
+ if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
+ goto done;
+
FdoD0ToD3(Fdo);
__FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
RtlZeroMemory(&Fdo->BalloonEvent, sizeof (KEVENT));
}
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
ThreadAlert(Fdo->SuspendThread);
ThreadJoin(Fdo->SuspendThread);
Fdo->SuspendThread = NULL;
FdoDisconnectInterrupt(Fdo);
+done:
RtlZeroMemory(&Fdo->Resource, sizeof (XENBUS_RESOURCE) * RESOURCE_COUNT);
__FdoSetDevicePnpState(Fdo, Stopped);
if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
goto done;
- KeClearEvent(&Fdo->ScanEvent);
- ThreadWake(Fdo->ScanThread);
+ if (__FdoIsActive(Fdo)) {
+ KeClearEvent(&Fdo->ScanEvent);
+ ThreadWake(Fdo->ScanThread);
- Trace("waiting for scan thread\n");
+ Trace("waiting for scan thread\n");
- (VOID) KeWaitForSingleObject(&Fdo->ScanEvent,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ (VOID) KeWaitForSingleObject(&Fdo->ScanEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
__FdoAcquireMutex(Fdo);
RtlZeroMemory(&Fdo->BalloonEvent, sizeof (KEVENT));
}
+ if (!__FdoIsActive(Fdo))
+ goto done;
+
ThreadAlert(Fdo->SuspendThread);
ThreadJoin(Fdo->SuspendThread);
Fdo->SuspendThread = NULL;
FdoDisconnectInterrupt(Fdo);
+done:
RtlZeroMemory(&Fdo->Resource, sizeof (XENBUS_RESOURCE) * RESOURCE_COUNT);
-done:
__FdoSetDevicePnpState(Fdo, Deleted);
Irp->IoStatus.Status = STATUS_SUCCESS;
for (;;) {
LARGE_INTEGER Timeout;
+ if (!__FdoIsActive(Fdo))
+ break;
+
Timeout.QuadPart = TIME_RELATIVE(TIME_S(SCAN_PAUSE));
status = KeWaitForSingleObject(&Fdo->ScanEvent,
RtlZeroMemory(BusInterface, sizeof (BUS_INTERFACE_STANDARD));
}
+static FORCEINLINE BOOLEAN
+__FdoIsBalloonEnabled(
+ VOID
+ )
+{
+ CHAR Key[] = "XEN:BALLOON=";
+ PANSI_STRING Option;
+ PCHAR Value;
+ BOOLEAN Enabled;
+ NTSTATUS status;
+
+ Enabled = TRUE;
+
+ status = RegistryQuerySystemStartOption(Key, &Option);
+ if (!NT_SUCCESS(status))
+ goto done;
+
+ Value = Option->Buffer + sizeof (Key) - 1;
+
+ if (strcmp(Value, "OFF") == 0)
+ Enabled = FALSE;
+
+ RegistryFreeSzValue(Option);
+
+done:
+ return Enabled;
+}
+
NTSTATUS
FdoCreate(
- IN PDEVICE_OBJECT PhysicalDeviceObject
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN BOOLEAN Active
)
{
- PDEVICE_OBJECT FunctionDeviceObject;
- PXENBUS_DX Dx;
- PXENBUS_FDO Fdo;
- WCHAR Name[MAXNAMELEN * sizeof (WCHAR)];
- ULONG Size;
- NTSTATUS status;
+ PDEVICE_OBJECT FunctionDeviceObject;
+ PXENBUS_DX Dx;
+ PXENBUS_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 (XENBUS_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;
- status = __FdoAcquireLowerBusInterface(Fdo);
- if (!NT_SUCCESS(status))
- goto fail7;
+ __FdoSetVendorName(Fdo, DeviceID);
+
+ __FdoSetName(Fdo);
- if (DriverParameters.Balloon != 0) {
+ __FdoSetActive(Fdo, Active);
+
+ if (__FdoIsActive(Fdo) &&
+ __FdoIsBalloonEnabled()) {
status = BalloonInitialize(&Fdo->Balloon);
if (!NT_SUCCESS(status))
- goto fail8;
- } else {
- Info("BALLOON DISABLED\n");
+ goto fail7;
}
InitializeMutex(&Fdo->Mutex);
return STATUS_SUCCESS;
-fail8:
- Error("fail8\n");
-
- __FdoReleaseLowerBusInterface(Fdo);
-
fail7:
Error("fail7\n");
+ __FdoSetActive(Fdo, FALSE);
+
+ RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
fail6:
Error("fail6\n");
+ __FdoReleaseLowerBusInterface(Fdo);
+
fail5:
Error("fail5\n");
Dx->Fdo = NULL;
- RtlZeroMemory(&Fdo->Mutex, sizeof (XENBUS_MUTEX));
+ RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
if (Fdo->Balloon != NULL) {
BalloonTeardown(Fdo->Balloon);
Fdo->Balloon = NULL;
}
+ __FdoSetActive(Fdo, FALSE);
+
+ RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
__FdoReleaseLowerBusInterface(Fdo);
ThreadAlert(Fdo->DevicePowerThread);
extern NTSTATUS
FdoCreate(
- IN PDEVICE_OBJECT PhysicalDeviceObject
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN BOOLEAN Active
);
extern VOID
extern NTSTATUS
FdoDelegateIrp(
- IN PXENBUS_FDO Fdo,
- IN PIRP Irp
+ IN PXENBUS_FDO Fdo,
+ IN PIRP Irp
);
extern VOID
FdoAddPhysicalDeviceObject(
- IN PXENBUS_FDO Fdo,
- IN PXENBUS_PDO Pdo
+ IN PXENBUS_FDO Fdo,
+ IN PXENBUS_PDO Pdo
);
extern VOID
FdoRemovePhysicalDeviceObject(
- IN PXENBUS_FDO Fdo,
- IN PXENBUS_PDO Pdo
+ IN PXENBUS_FDO Fdo,
+ IN PXENBUS_PDO Pdo
);
extern VOID
FdoAcquireMutex(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
extern VOID
FdoReleaseMutex(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
extern PDEVICE_OBJECT
IN PXENBUS_FDO Fdo
);
+PCHAR
+FdoGetVendorName(
+ IN PXENBUS_FDO Fdo
+ );
+
extern PXENBUS_RESOURCE
FdoGetResource(
IN PXENBUS_FDO Fdo,
extern PXENBUS_SUSPEND_INTERFACE
FdoGetSuspendInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
#include "shared_info.h"
extern PXENBUS_SHARED_INFO_INTERFACE
FdoGetSharedInfoInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
#include "evtchn.h"
extern PXENBUS_EVTCHN_INTERFACE
FdoGetEvtchnInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
#include "debug.h"
extern PXENBUS_DEBUG_INTERFACE
FdoGetDebugInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
#include "store.h"
extern PXENBUS_STORE_INTERFACE
FdoGetStoreInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
#include "gnttab.h"
extern PXENBUS_GNTTAB_INTERFACE
FdoGetGnttabInterface(
- IN PXENBUS_FDO Fdo
+ IN PXENBUS_FDO Fdo
);
extern NTSTATUS
#include "gnttab.h"
#include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define GNTTAB_MAXIMUM_ENTRY_FRAME_COUNT 32
+++ /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 _XENBUS_HIGH_H
-#define _XENBUS_HIGH_H
-
-#include <ntddk.h>
-
-#pragma warning(disable:4127) // conditional expression is constant
-
-typedef LONG HIGH_LOCK, *PHIGH_LOCK;
-
-#define LOCK_MAGIC 0xFEEDFACE
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_raisesIRQL(HIGH_LEVEL)
-__drv_savesIRQL
-KIRQL
-__AcquireHighLock(
- IN PHIGH_LOCK Lock
- )
-{
- KIRQL Irql;
-
- KeRaiseIrql(HIGH_LEVEL, &Irql);
-
- while (InterlockedCompareExchange(Lock, LOCK_MAGIC, 0) != 0)
- _mm_pause();
-
- KeMemoryBarrier();
-
- return Irql;
-}
-
-#define AcquireHighLock(_Lock, _Irql) \
- do { \
- *(_Irql) = __AcquireHighLock(_Lock); \
- } while (FALSE)
-
-static FORCEINLINE
-__drv_maxIRQL(HIGH_LEVEL)
-__drv_requiresIRQL(HIGH_LEVEL)
-VOID
-ReleaseHighLock(
- IN PHIGH_LOCK Lock,
- IN __drv_restoresIRQL KIRQL Irql
- )
-{
- KeMemoryBarrier();
-
- InterlockedExchange(Lock, 0);
- KeLowerIrql(Irql);
-}
-
-static FORCEINLINE
-VOID
-InitializeHighLock(
- IN PHIGH_LOCK Lock
- )
-{
- RtlZeroMemory(&Lock, sizeof (HIGH_LOCK));
-}
-
-#endif // _XENBUS_HIGH_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 _XENBUS_LOG_H
-#define _XENBUS_LOG_H
-
-#define __MODULE__ "XENBUS"
-
-#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 // _XENBUS_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.
- */
-
-#ifndef _XENBUS_MUTEX_H
-#define _XENBUS_MUTEX_H
-
-#include <ntddk.h>
-
-#include "assert.h"
-
-typedef struct _XENBUS_MUTEX {
- PKTHREAD Owner;
- KEVENT Event;
-} XENBUS_MUTEX, *PXENBUS_MUTEX;
-
-static FORCEINLINE VOID
-InitializeMutex(
- IN PXENBUS_MUTEX Mutex
- )
-{
- RtlZeroMemory(Mutex, sizeof (XENBUS_MUTEX));
-
- KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
- IN PXENBUS_MUTEX Mutex
- )
-{
- (VOID) KeWaitForSingleObject(&Mutex->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ASSERT3P(Mutex->Owner, ==, NULL);
- Mutex->Owner = KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
- IN PXENBUS_MUTEX Mutex
- )
-{
- ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
- Mutex->Owner = NULL;
-
- KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
-}
-
-#endif // _XENBUS_MUTEX_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 _XENBUS_NAMES_H_
-#define _XENBUS_NAMES_H_
-
-#include <ntddk.h>
-
-#include "types.h"
-
-static FORCEINLINE const CHAR *
-PowerTypeName(
- IN POWER_STATE_TYPE Type
- )
-{
-#define _POWER_TYPE_NAME(_Type) \
- case _Type: \
- return #_Type;
-
- switch (Type) {
- _POWER_TYPE_NAME(SystemPowerState);
- _POWER_TYPE_NAME(DevicePowerState);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerSystemStateName(
- IN SYSTEM_POWER_STATE State
- )
-{
-#define _POWER_SYSTEM_STATE_NAME(_State) \
- case PowerSystem ## _State: \
- return #_State;
-
- switch (State) {
- _POWER_SYSTEM_STATE_NAME(Unspecified);
- _POWER_SYSTEM_STATE_NAME(Working);
- _POWER_SYSTEM_STATE_NAME(Sleeping1);
- _POWER_SYSTEM_STATE_NAME(Sleeping2);
- _POWER_SYSTEM_STATE_NAME(Sleeping3);
- _POWER_SYSTEM_STATE_NAME(Hibernate);
- _POWER_SYSTEM_STATE_NAME(Shutdown);
- _POWER_SYSTEM_STATE_NAME(Maximum);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_SYSTEM_STATE_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerDeviceStateName(
- IN DEVICE_POWER_STATE State
- )
-{
-#define _POWER_DEVICE_STATE_NAME(_State) \
- case PowerDevice ## _State: \
- return #_State;
-
- switch (State) {
- _POWER_DEVICE_STATE_NAME(Unspecified);
- _POWER_DEVICE_STATE_NAME(D0);
- _POWER_DEVICE_STATE_NAME(D1);
- _POWER_DEVICE_STATE_NAME(D2);
- _POWER_DEVICE_STATE_NAME(D3);
- _POWER_DEVICE_STATE_NAME(Maximum);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_DEVICE_STATE_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerActionName(
- IN POWER_ACTION Type
- )
-{
-#define _POWER_ACTION_NAME(_Type) \
- case PowerAction ## _Type: \
- return #_Type;
-
- switch (Type) {
- _POWER_ACTION_NAME(None);
- _POWER_ACTION_NAME(Reserved);
- _POWER_ACTION_NAME(Sleep);
- _POWER_ACTION_NAME(Hibernate);
- _POWER_ACTION_NAME(Shutdown);
- _POWER_ACTION_NAME(ShutdownReset);
- _POWER_ACTION_NAME(ShutdownOff);
- _POWER_ACTION_NAME(WarmEject);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PowerMinorFunctionName(
- IN ULONG MinorFunction
- )
-{
-#define _POWER_MINOR_FUNCTION_NAME(_Function) \
- case IRP_MN_ ## _Function: \
- return #_Function;
-
- switch (MinorFunction) {
- _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
- _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
- _POWER_MINOR_FUNCTION_NAME(SET_POWER);
- _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
-
- default:
- return "UNKNOWN";
- }
-
-#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
- )
-{
-#define _PNP_MINOR_FUNCTION_NAME(_Function) \
- case IRP_MN_ ## _Function: \
- return #_Function;
-
- switch (Function) {
- _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
- _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
- _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
- _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
- _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
- _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
- _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
- _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
- _PNP_MINOR_FUNCTION_NAME(EJECT);
- _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
- _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
- _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
- _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
- _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
- _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _PNP_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const CHAR *
-PartialResourceDescriptorTypeName(
- IN UCHAR Type
- )
-{
-#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type) \
- case CmResourceType ## _Type: \
- return #_Type;
-
- switch (Type) {
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#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
-}
-
-#endif // _XENBUS_NAMES_H_
#include <ntstrsafe.h>
#include <util.h>
-#include <binding.h>
#include <shared_info_interface.h>
#include <evtchn_interface.h>
#include <debug_interface.h>
#include "bus.h"
#include "driver.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define PDO_TAG 'ODP'
+#define MAXNAMELEN 128
+
struct _XENBUS_PDO {
PXENBUS_DX Dx;
PXENBUS_THREAD DevicePowerThread;
PIRP DevicePowerIrp;
+ CHAR Class[MAXNAMELEN];
+
PXENBUS_FDO Fdo;
BOOLEAN Missing;
const CHAR *Reason;
- UCHAR Revision;
BUS_INTERFACE_STANDARD BusInterface;
}
static FORCEINLINE VOID
-__PdoSetName(
+__PdoSetClass(
IN PXENBUS_PDO Pdo,
- IN PANSI_STRING Ansi
+ IN PANSI_STRING Class
)
{
- PXENBUS_DX Dx = Pdo->Dx;
NTSTATUS status;
- status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%Z", Ansi);
+ status = RtlStringCbPrintfA(Pdo->Class,
+ MAXNAMELEN,
+ "%Z",
+ Class);
ASSERT(NT_SUCCESS(status));
}
static FORCEINLINE PCHAR
-__PdoGetName(
+__PdoGetClass(
IN PXENBUS_PDO Pdo
)
{
- PXENBUS_DX Dx = Pdo->Dx;
-
- return Dx->Name;
-}
-
-PCHAR
-PdoGetName(
- IN PXENBUS_PDO Pdo
- )
-{
- return __PdoGetName(Pdo);
+ return Pdo->Class;
}
struct _REVISION_ENTRY {
const CHAR *Name;
- UCHAR Revision;
+ ULONG Revision;
};
static struct _REVISION_ENTRY PdoRevisionTable[] = {
- { "VIF", 0x02 },
- { "VBD", 0x02 },
- { "IFACE", 0x02 },
+ { "VIF", 1 },
+ { "VBD", 1 },
+ { "IFACE", 1 },
{ NULL, 0 }
};
-static FORCEINLINE VOID
-__PdoSetRevision(
- IN PXENBUS_PDO Pdo,
- IN PANSI_STRING Name
+static FORCEINLINE ULONG
+__PdoGetRevision(
+ IN PXENBUS_PDO Pdo
)
{
struct _REVISION_ENTRY *Entry;
-
- Pdo->Revision = PCI_REVISION;
-
+ ULONG Revision;
+
+ Revision = 0;
for (Entry = PdoRevisionTable; Entry->Name != NULL; Entry++) {
- if (strcmp(Name->Buffer, Entry->Name) == 0) {
- Trace("%s: %02x\n",
- __PdoGetName(Pdo),
- Entry->Revision);
- Pdo->Revision = Entry->Revision;
+ if (strcmp(__PdoGetClass(Pdo), Entry->Name) == 0) {
+ Revision = Entry->Revision;
break;
}
}
+
+ return Revision;
}
-static FORCEINLINE UCHAR
-__PdoGetRevision(
+static FORCEINLINE VOID
+__PdoSetName(
+ IN PXENBUS_PDO Pdo,
+ IN PCHAR VendorName
+ )
+{
+ PXENBUS_DX Dx = Pdo->Dx;
+ NTSTATUS status;
+
+ status = RtlStringCbPrintfA(Dx->Name,
+ MAX_DEVICE_ID_LEN,
+ "VEN_%s&DEV_%s&REV_%08X",
+ VendorName,
+ __PdoGetClass(Pdo),
+ __PdoGetRevision(Pdo));
+ ASSERT(NT_SUCCESS(status));
+}
+
+static FORCEINLINE PCHAR
+__PdoGetName(
IN PXENBUS_PDO Pdo
)
{
- return Pdo->Revision;
+ PXENBUS_DX Dx = Pdo->Dx;
+
+ return Dx->Name;
+}
+
+PCHAR
+PdoGetName(
+ IN PXENBUS_PDO Pdo
+ )
+{
+ return __PdoGetName(Pdo);
}
static FORCEINLINE PDEVICE_OBJECT
MAXTEXTLEN,
L"%hs %hs",
FdoGetName(__PdoGetFdo(Pdo)),
- __PdoGetName(Pdo));
+ __PdoGetClass(Pdo));
ASSERT(NT_SUCCESS(status));
Buffer += wcslen(Buffer);
status = RtlStringCbPrintfW(Buffer,
MAXTEXTLEN,
L"%hs",
- __PdoGetName(Pdo));
+ __PdoGetClass(Pdo));
ASSERT(NT_SUCCESS(status));
Buffer += wcslen(Buffer);
status = RtlStringCbPrintfW(Buffer,
MAX_DEVICE_ID_LEN,
- L"XENBUS\\CLASS_%hs&REV_%02X",
- __PdoGetName(Pdo),
- __PdoGetRevision(Pdo));
+ L"XENBUS\\%hs",
+ __PdoGetName(Pdo));
ASSERT(NT_SUCCESS(status));
Buffer += wcslen(Buffer);
Length = MAX_DEVICE_ID_LEN;
status = RtlStringCbPrintfW(Buffer,
Length,
- L"XENBUS\\CLASS_%hs&REV_%02X",
- __PdoGetName(Pdo),
- __PdoGetRevision(Pdo));
+ L"XENBUS\\%hs",
+ __PdoGetName(Pdo));
ASSERT(NT_SUCCESS(status));
Buffer += wcslen(Buffer);
NTSTATUS
PdoCreate(
IN PXENBUS_FDO Fdo,
- IN PANSI_STRING Name
+ IN PANSI_STRING Class
)
{
PDEVICE_OBJECT PhysicalDeviceObject;
NTSTATUS status;
#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
- status = IoCreateDevice(DriverObject,
+ status = IoCreateDevice(DriverGetDriverObject(),
sizeof(XENBUS_DX),
NULL,
FILE_DEVICE_UNKNOWN,
if (!NT_SUCCESS(status))
goto fail5;
- __PdoSetName(Pdo, Name);
- __PdoSetRevision(Pdo, Name);
+ __PdoSetClass(Pdo, Class);
+ __PdoSetName(Pdo, FdoGetVendorName(Fdo));
- Info("%p (XENBUS\\CLASS_%s&REV_%02X#_)\n",
+ Info("%p (%s)\n",
PhysicalDeviceObject,
- __PdoGetName(Pdo),
- __PdoGetRevision(Pdo));
+ __PdoGetName(Pdo));
Dx->Pdo = Pdo;
PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
__PdoUnlink(Pdo);
- Info("%p (XENBUS\\CLASS_%s&REV_%02X) (%s)\n",
+ Info("%p (%s) (%s)\n",
PhysicalDeviceObject,
__PdoGetName(Pdo),
- __PdoGetRevision(Pdo),
Pdo->Reason);
Pdo->Reason = NULL;
Dx->Pdo = NULL;
- Pdo->Revision = 0;
+ RtlZeroMemory(Pdo->Class, MAXNAMELEN);
ThreadAlert(Pdo->DevicePowerThread);
ThreadJoin(Pdo->DevicePowerThread);
#include <util.h>
#include "range_set.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define RANGE_SET_AUDIT DBG
+++ /dev/null
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <ntddk.h>
-#include <util.h>
-
-#include "registry.h"
-#include "log.h"
-#include "assert.h"
-
-#define REGISTRY_POOL 'GERX'
-
-static UNICODE_STRING RegistryPath;
-
-static FORCEINLINE PVOID
-__RegistryAllocate(
- IN ULONG Length
- )
-{
- return __AllocateNonPagedPoolWithTag(Length, REGISTRY_POOL);
-}
-
-static FORCEINLINE VOID
-__RegistryFree(
- IN PVOID Buffer
- )
-{
- __FreePoolWithTag(Buffer, REGISTRY_POOL);
-}
-
-NTSTATUS
-RegistryInitialize(
- IN PUNICODE_STRING Path
- )
-{
- NTSTATUS status;
-
- ASSERT3P(RegistryPath.Buffer, ==, NULL);
-
- status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-VOID
-RegistryTeardown(
- VOID
- )
-{
- RtlFreeUnicodeString(&RegistryPath);
- RegistryPath.Buffer = NULL;
- RegistryPath.MaximumLength = RegistryPath.Length = 0;
-}
-
-NTSTATUS
-RegistryOpenServiceKey(
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
- )
-{
- OBJECT_ATTRIBUTES Attributes;
- NTSTATUS status;
-
- InitializeObjectAttributes(&Attributes,
- &RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
-
- status = ZwOpenKey(Key,
- DesiredAccess,
- &Attributes);
- if (!NT_SUCCESS(status))
- 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,
- Key,
- NULL);
-
- status = ZwOpenKey(SubKey,
- DesiredAccess,
- &Attributes);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryCreateSubKey(
- IN PHANDLE Key,
- IN PCHAR Name
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- OBJECT_ATTRIBUTES Attributes;
- HANDLE SubKey;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- InitializeObjectAttributes(&Attributes,
- &Unicode,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- Key,
- NULL);
-
- status = ZwCreateKey(&SubKey,
- KEY_ALL_ACCESS,
- &Attributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE,
- NULL
- );
- if (!NT_SUCCESS(status))
- goto fail2;
-
- ZwClose(SubKey);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryDeleteSubKey(
- IN PHANDLE Key,
- IN PCHAR Name
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- OBJECT_ATTRIBUTES Attributes;
- HANDLE SubKey;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- InitializeObjectAttributes(&Attributes,
- &Unicode,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- Key,
- NULL);
-
- status = ZwOpenKey(&SubKey,
- KEY_ALL_ACCESS,
- &Attributes);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- status = ZwDeleteKey(SubKey);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- ZwClose(SubKey);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- ZwClose(SubKey);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryEnumerateSubKeys(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- )
-{
- ULONG Size;
- NTSTATUS status;
- PKEY_FULL_INFORMATION Full;
- PKEY_BASIC_INFORMATION Basic;
- ULONG Index;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail1;
-
- Full = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Full == NULL)
- goto fail2;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- Full,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
- Full->MaxNameLen;
-
- Basic = __RegistryAllocate(Size);
- status = STATUS_NO_MEMORY;
- if (Basic == NULL)
- goto fail4;
-
- for (Index = 0; Index < Full->SubKeys; Index++) {
- UNICODE_STRING Unicode;
- ANSI_STRING Ansi;
-
- status = ZwEnumerateKey(Key,
- Index,
- KeyBasicInformation,
- Basic,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- Unicode.MaximumLength = (USHORT)Basic->NameLength;
- Unicode.Buffer = Basic->Name;
- Unicode.Length = (USHORT)Basic->NameLength;
-
- Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
- Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
-
- status = 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
-RegistryEnumerateValues(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- )
-{
- ULONG Size;
- NTSTATUS status;
- PKEY_FULL_INFORMATION Full;
- PKEY_VALUE_BASIC_INFORMATION Basic;
- ULONG Index;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail1;
-
- Full = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Full == NULL)
- goto fail2;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- Full,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
- Full->MaxValueNameLen;
-
- Basic = __RegistryAllocate(Size);
- status = STATUS_NO_MEMORY;
- if (Basic == NULL)
- goto fail4;
-
- for (Index = 0; Index < Full->Values; Index++) {
- UNICODE_STRING Unicode;
- ANSI_STRING Ansi;
-
- status = ZwEnumerateValueKey(Key,
- Index,
- KeyValueBasicInformation,
- Basic,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- Unicode.MaximumLength = (USHORT)Basic->NameLength;
- Unicode.Buffer = Basic->Name;
- Unicode.Length = (USHORT)Basic->NameLength;
-
- Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
- Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
-
- status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
- status = Callback(Context, Key, Ansi.Buffer);
-
- __RegistryFree(Ansi.Buffer);
-
- if (!NT_SUCCESS(status))
- goto fail6;
- }
-
- __RegistryFree(Basic);
-
- __RegistryFree(Full);
-
- return STATUS_SUCCESS;
-
-fail6:
-fail5:
- __RegistryFree(Basic);
-
-fail4:
-fail3:
- __RegistryFree(Full);
-
-fail2:
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryQueryDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PULONG Value
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- ULONG Size;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail2;
-
- Partial = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail3;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- Partial,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = STATUS_INVALID_PARAMETER;
- if (Partial->Type != REG_DWORD ||
- Partial->DataLength != sizeof (ULONG))
- goto fail5;
-
- *Value = *(PULONG)Partial->Data;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail5:
-fail4:
- __RegistryFree(Partial);
-
-fail3:
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryUpdateDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Value
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- sizeof (ULONG));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail2;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_DWORD;
- Partial->DataLength = sizeof (ULONG);
- *(PULONG)Partial->Data = Value;
-
- status = ZwSetValueKey(Key,
- &Unicode,
- Partial->TitleIndex,
- Partial->Type,
- Partial->Data,
- Partial->DataLength);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- __RegistryFree(Partial);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
-
- return status;
-}
-
-static PANSI_STRING
-RegistrySzToAnsi(
- IN PWCHAR Buffer
- )
-{
- PANSI_STRING Ansi;
- ULONG Length;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
- status = STATUS_NO_MEMORY;
- if (Ansi == NULL)
- goto fail1;
-
- Length = (ULONG)wcslen(Buffer);
- Ansi[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
- Ansi[0].Buffer = __RegistryAllocate(Ansi[0].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (Ansi[0].Buffer == NULL)
- goto fail2;
-
- RtlInitUnicodeString(&Unicode, Buffer);
- status = RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi[0].Length = (USHORT)Length * sizeof (CHAR);
-
- return Ansi;
-
-fail2:
- __RegistryFree(Ansi);
-
-fail1:
- return NULL;
-}
-
-static PANSI_STRING
-RegistryMultiSzToAnsi(
- IN PWCHAR Buffer
- )
-{
- PANSI_STRING Ansi;
- LONG Index;
- LONG Count;
- NTSTATUS status;
-
- Index = 0;
- Count = 0;
- for (;;) {
- ULONG Length;
-
- Length = (ULONG)wcslen(&Buffer[Index]);
- if (Length == 0)
- break;
-
- Index += Length + 1;
- Count++;
- }
-
- Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
-
- status = STATUS_NO_MEMORY;
- if (Ansi == NULL)
- goto fail1;
-
- for (Index = 0; Index < Count; Index++) {
- ULONG Length;
- UNICODE_STRING Unicode;
-
- Length = (ULONG)wcslen(Buffer);
- Ansi[Index].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
- Ansi[Index].Buffer = __RegistryAllocate(Ansi[Index].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (Ansi[Index].Buffer == NULL)
- goto fail2;
-
- RtlInitUnicodeString(&Unicode, Buffer);
-
- status = RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi[Index].Length = (USHORT)Length * sizeof (CHAR);
- Buffer += Length + 1;
- }
-
- return Ansi;
-
-fail2:
- while (--Index >= 0)
- __RegistryFree(Ansi[Index].Buffer);
-
- __RegistryFree(Ansi);
-
-fail1:
- return NULL;
-}
-
-NTSTATUS
-RegistryQuerySzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PANSI_STRING *Array
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Value;
- ULONG Size;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail2;
-
- Value = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Value == NULL)
- goto fail3;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- Value,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- switch (Value->Type) {
- case REG_SZ:
- status = STATUS_NO_MEMORY;
- *Array = RegistrySzToAnsi((PWCHAR)Value->Data);
- break;
-
- case REG_MULTI_SZ:
- status = STATUS_NO_MEMORY;
- *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data);
- break;
-
- default:
- status = STATUS_INVALID_PARAMETER;
- *Array = NULL;
- break;
- }
-
- if (*Array == NULL)
- goto fail5;
-
- __RegistryFree(Value);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail5:
-fail4:
- __RegistryFree(Value);
-
-fail3:
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryQuerySystemStartOptions(
- OUT PANSI_STRING *Options
- )
-{
- UNICODE_STRING Unicode;
- OBJECT_ATTRIBUTES Attributes;
- HANDLE Key;
- PKEY_VALUE_PARTIAL_INFORMATION Value;
- ULONG Size;
- 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;
-
- Value = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Value == NULL)
- goto fail3;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- Value,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = STATUS_INVALID_PARAMETER;
- if (Value->Type != REG_SZ)
- goto fail5;
-
- *Options = RegistrySzToAnsi((PWCHAR)Value->Data);
-
- status = STATUS_NO_MEMORY;
- if (*Options == NULL)
- goto fail6;
-
- __RegistryFree(Value);
-
- ZwClose(Key);
-
- return STATUS_SUCCESS;
-
-fail6:
-fail5:
-fail4:
- __RegistryFree(Value);
-
-fail3:
-fail2:
- ZwClose(Key);
-
-fail1:
- return status;
-}
-
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToSz(
- PANSI_STRING Ansi
- )
-{
- ULONG Length;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Length = Ansi->Length + 1;
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- Length * sizeof (WCHAR));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail1;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_SZ;
- Partial->DataLength = Length * sizeof (WCHAR);
-
- Unicode.MaximumLength = (UCHAR)Partial->DataLength;
- Unicode.Buffer = (PWCHAR)Partial->Data;
- Unicode.Length = 0;
-
- status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- return Partial;
-
-fail2:
- __RegistryFree(Partial);
-
-fail1:
- return NULL;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToMultiSz(
- PANSI_STRING Ansi
- )
-{
- ULONG Length;
- ULONG Index;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Length = 1;
- for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
- Length += Ansi[Index].Length + 1;
-
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- Length * sizeof (WCHAR));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail1;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_MULTI_SZ;
- Partial->DataLength = Length * sizeof (WCHAR);
-
- Unicode.MaximumLength = (USHORT)Partial->DataLength;
- Unicode.Buffer = (PWCHAR)Partial->Data;
- Unicode.Length = 0;
-
- for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- Length = Unicode.Length / sizeof (WCHAR);
-
- ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
- Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
- Unicode.Buffer += Length + 1;
- Unicode.Length = 0;
- }
- *Unicode.Buffer = L'\0';
-
- return Partial;
-
-fail2:
- __RegistryFree(Partial);
-
-fail1:
- return NULL;
-}
-
-NTSTATUS
-RegistryUpdateSzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Type,
- ...
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- va_list Arguments;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- va_start(Arguments, Type);
- switch (Type) {
- case REG_SZ: {
- PANSI_STRING Argument;
-
- Argument = va_arg(Arguments, PANSI_STRING);
-
- status = STATUS_NO_MEMORY;
- Partial = RegistryAnsiToSz(Argument);
- break;
- }
- case REG_MULTI_SZ: {
- PANSI_STRING Argument;
-
- Argument = va_arg(Arguments, PANSI_STRING);
-
- status = STATUS_NO_MEMORY;
- Partial = RegistryAnsiToMultiSz(Argument);
- break;
- }
- default:
- status = STATUS_INVALID_PARAMETER;
- Partial = NULL;
- break;
- }
- va_end(Arguments);
-
- if (Partial == NULL)
- goto fail2;
-
- status = ZwSetValueKey(Key,
- &Unicode,
- Partial->TitleIndex,
- Partial->Type,
- Partial->Data,
- Partial->DataLength);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- __RegistryFree(Partial);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-VOID
-RegistryFreeSzValue(
- IN PANSI_STRING Array
- )
-{
- ULONG Index;
-
- if (Array == NULL)
- return;
-
- for (Index = 0; Array[Index].Buffer != NULL; Index++)
- __RegistryFree(Array[Index].Buffer);
-
- __RegistryFree(Array);
-}
-
-VOID
-RegistryCloseKey(
- IN HANDLE Key
- )
-{
- ZwClose(Key);
-}
+++ /dev/null
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _XENBUS_REGISTRY_H
-#define _XENBUS_REGISTRY_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-RegistryInitialize(
- IN PUNICODE_STRING Path
- );
-
-extern VOID
-RegistryTeardown(
- 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 SubKey
- );
-
-extern NTSTATUS
-RegistryCreateSubKey(
- IN HANDLE Key,
- IN PCHAR Name
- );
-
-extern NTSTATUS
-RegistryDeleteSubKey(
- IN HANDLE Key,
- IN PCHAR Name
- );
-
-extern NTSTATUS
-RegistryEnumerateSubKeys(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- );
-
-extern NTSTATUS
-RegistryEnumerateValues(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- );
-
-extern NTSTATUS
-RegistryQueryDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PULONG Value
- );
-
-extern NTSTATUS
-RegistryUpdateDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Value
- );
-
-extern NTSTATUS
-RegistryQuerySzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PANSI_STRING *Array
- );
-
-extern NTSTATUS
-RegistryQuerySystemStartOptions(
- OUT PANSI_STRING *Options
- );
-
-extern VOID
-RegistryFreeSzValue(
- IN PANSI_STRING Array
- );
-
-extern NTSTATUS
-RegistryUpdateSzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Type,
- ...
- );
-
-extern VOID
-RegistryCloseKey(
- IN HANDLE Key
- );
-
-#endif // _XENBUS_REGISTRY_H
#include "shared_info.h"
#include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
struct _XENBUS_SHARED_INFO_CONTEXT {
#include "store.h"
#include "evtchn.h"
-#include "debug.h"
#include "fdo.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define STORE_TRANSACTION_MAGIC 'NART'
#include "suspend.h"
#include "thread.h"
#include "fdo.h"
-#include "log.h"
#include "sync.h"
+#include "dbg_print.h"
#include "assert.h"
struct _XENBUS_SUSPEND_CALLBACK {
KeAcquireSpinLock(&Context->Lock, &Irql);
- LogQemuPrintf("SUSPEND: ====>\n");
+ LogPrintf(LOG_LEVEL_INFO,
+ "SUSPEND: ====>\n");
SyncCapture();
SyncDisableInterrupts();
- LogQemuPrintf("SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend ====>\n");
+ LogPrintf(LOG_LEVEL_INFO,
+ "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend ====>\n");
status = SchedShutdown(SHUTDOWN_suspend);
- LogQemuPrintf("SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend <==== (%08x)\n", status);
+ LogPrintf(LOG_LEVEL_INFO,
+ "SUSPEND: SCHEDOP_shutdown:SHUTDOWN_suspend <==== (%08x)\n",
+ status);
if (NT_SUCCESS(status)) {
PLIST_ENTRY ListEntry;
if (NT_SUCCESS(status)) {
PLIST_ENTRY ListEntry;
- // Make sure that emulated devices don't magically re-appear
- UnplugReplay();
-
for (ListEntry = Context->LateList.Flink;
ListEntry != &Context->LateList;
ListEntry = ListEntry->Flink) {
SyncRelease();
- LogQemuPrintf("SUSPEND: <====\n");
+ LogPrintf(LOG_LEVEL_INFO, "SUSPEND: <====\n");
KeReleaseSpinLock(&Context->Lock, Irql);
}
#include <util.h>
#include "sync.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
// Routines to capture all CPUs in a spinning state with interrupts
} while (InterlockedCompareExchange(&SyncContext.CompletionCount, New, Old) != Old);
if (Old < CpuCount) {
- LogQemuPrintf("SYNC: %d < %d\n", Old, CpuCount);
+ LogPrintf(LOG_LEVEL_WARNING,
+ "SYNC: %d < %d\n",
+ Old,
+ CpuCount);
#pragma prefast(suppress:28138) // Use constant rather than variable
KeLowerIrql(DISPATCH_LEVEL);
#include <util.h>
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define THREAD_POOL 'ERHT'
+++ /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 _XENFILT_ASSERT_H
-#define _XENFILT_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); \
- __analysis_assume(_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 // _XENFILT_ASSERT_H
-
*/
#include <ntddk.h>
+#include <xen.h>
#include <util.h>
#include "fdo.h"
#include "pdo.h"
-#include "emulated.h"
#include "registry.h"
#include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#include "version.h"
-extern const CHAR *XenVersion;
+extern PULONG InitSafeBootMode;
-extern PULONG InitSafeBootMode;
+typedef struct _XENFILT_DRIVER {
+ PDRIVER_OBJECT DriverObject;
+ HANDLE ParametersKey;
+} XENFILT_DRIVER, *PXENFILT_DRIVER;
-PDRIVER_OBJECT DriverObject;
+static XENFILT_DRIVER Driver;
-static HANDLE DriverServiceKey;
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ Driver.DriverObject = DriverObject;
+}
-static PANSI_STRING DriverFilterDevices;
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+ VOID
+ )
+{
+ return Driver.DriverObject;
+}
-static XENFILT_EMULATED_INTERFACE DriverEmulatedInterface;
+PDRIVER_OBJECT
+DriverGetDriverObject(
+ VOID
+ )
+{
+ return __DriverGetDriverObject();
+}
-DRIVER_UNLOAD DriverUnload;
+static FORCEINLINE VOID
+__DriverSetParametersKey(
+ IN HANDLE Key
+ )
+{
+ Driver.ParametersKey = Key;
+}
-PXENFILT_EMULATED_INTERFACE
-DriverGetEmulatedInterface(
+static FORCEINLINE HANDLE
+__DriverGetParametersKey(
VOID
)
{
- return &DriverEmulatedInterface;
+ 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;
- Trace("====>\n");
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
- Info("%s (%s)\n",
- MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
- DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ Trace("====>\n");
if (*InitSafeBootMode > 0)
goto done;
- EmulatedTeardown(&DriverEmulatedInterface);
-
- RegistryDeleteSubKey(DriverServiceKey, "Status");
-
- RegistryFreeSzValue(DriverFilterDevices);
-
- RegistryCloseKey(DriverServiceKey);
+ ParametersKey = __DriverGetParametersKey();
+ if (ParametersKey != NULL) {
+ RegistryCloseKey(ParametersKey);
+ __DriverSetParametersKey(NULL);
+ }
RegistryTeardown();
done:
- DriverObject = NULL;
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER)));
Trace("<====\n");
}
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
-DriverQueryCompletion(
+DriverQueryIdCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp,
- DriverQueryCompletion,
+ DriverQueryIdCompletion,
&Event,
TRUE,
TRUE,
NTSTATUS
#pragma prefast(suppress:28152) // Does not clear DO_DEVICE_INITIALIZING
AddDevice(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
+ HANDLE ParametersKey;
+ PANSI_STRING FilterDevices;
PWCHAR DeviceID;
UNICODE_STRING Unicode;
ANSI_STRING Ansi;
ULONG Index;
NTSTATUS status;
- ASSERT3P(_DriverObject, ==, DriverObject);
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
+
+ ParametersKey = __DriverGetParametersKey();
+
+ FilterDevices = NULL;
+ if (ParametersKey != NULL) {
+ status = RegistryQuerySzValue(ParametersKey,
+ "FilterDevices",
+ &FilterDevices);
+ ASSERT(IMPLY(!NT_SUCCESS(status), FilterDevices == NULL));
+ } else {
+ FilterDevices = NULL;
+ }
+
+ if (FilterDevices == NULL)
+ goto done;
status = __DriverQueryId(PhysicalDeviceObject, BusQueryDeviceID, &DeviceID);
if (!NT_SUCCESS(status))
if (!NT_SUCCESS(status))
goto fail2;
- for (Index = 0;
- DriverFilterDevices != NULL && DriverFilterDevices[Index].Buffer != NULL;
- Index++) {
- PANSI_STRING Device = &DriverFilterDevices[Index];
+ for (Index = 0; FilterDevices[Index].Buffer != NULL; Index++) {
+ PANSI_STRING Device = &FilterDevices[Index];
if (RtlCompareString(&Ansi, Device, TRUE) == 0) {
status = FdoCreate(PhysicalDeviceObject, &Ansi);
if (!NT_SUCCESS(status))
goto fail3;
- goto done;
+ break;
}
}
-done:
RtlFreeAnsiString(&Ansi);
ExFreePool(DeviceID);
+ RegistryFreeSzValue(FilterDevices);
+
+done:
return STATUS_SUCCESS;
fail3:
+ Error("fail3\n");
+
RtlFreeAnsiString(&Ansi);
fail2:
+ Error("fail2\n");
+
ExFreePool(DeviceID);
fail1:
+ RegistryFreeSzValue(FilterDevices);
+
+ Error("fail1 (%08x)\n", status);
+
return status;
}
NTSTATUS
DriverEntry(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
+ HANDLE ServiceKey;
HANDLE ParametersKey;
ULONG Index;
NTSTATUS status;
- ASSERT3P(DriverObject, ==, NULL);
+ ASSERT3P(__DriverGetDriverObject(), ==, NULL);
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+ __DbgPrintEnable();
+
Trace("====>\n");
- Info("%s (%s)\n",
- MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
- DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ __DriverSetDriverObject(DriverObject);
- DriverObject = _DriverObject;
DriverObject->DriverUnload = DriverUnload;
if (*InitSafeBootMode > 0)
goto done;
+ LogPrintf(LOG_LEVEL_INFO,
+ "XENFILT %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 = RegistryOpenServiceKey(KEY_READ, &DriverServiceKey);
+ status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
if (!NT_SUCCESS(status))
goto fail2;
- status = RegistryOpenSubKey(DriverServiceKey, "Parameters", KEY_READ, &ParametersKey);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- (VOID) RegistryQuerySzValue(ParametersKey, "FilterDevices", &DriverFilterDevices);
-
- status = RegistryCreateSubKey(DriverServiceKey, "Status");
- if (!NT_SUCCESS(status))
- goto fail4;
+ status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
+ if (NT_SUCCESS(status))
+ __DriverSetParametersKey(ParametersKey);
- status = EmulatedInitialize(&DriverEmulatedInterface);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- RegistryCloseKey(ParametersKey);
+ RegistryCloseKey(ServiceKey);
DriverObject->DriverExtension->AddDevice = AddDevice;
Trace("<====\n");
return STATUS_SUCCESS;
-fail5:
- Error("fail5\n");
-
- RegistryDeleteSubKey(DriverServiceKey, "Status");
-
-fail4:
- Error("fail4\n");
-
- RegistryCloseKey(ParametersKey);
-
-fail3:
- Error("fail3\n");
-
- RegistryCloseKey(DriverServiceKey);
-
fail2:
Error("fail2\n");
fail1:
Error("fail1 (%08x)\n", status);
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER)));
+
return status;
}
#include "pdo.h"
#include "fdo.h"
-extern PDRIVER_OBJECT DriverObject;
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+ VOID
+ );
-extern LONG DriverInitialized;
+extern HANDLE
+DriverGetParametersKey(
+ VOID
+ );
#define MAX_DEVICE_ID_LEN 200
#pragma warning(pop)
-extern PXENFILT_EMULATED_INTERFACE
-DriverGetEmulatedInterface(
- VOID
- );
-
#endif // _XENFILT_DRIVER_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 <ntstrsafe.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <xen.h>
-#include <util.h>
-
-#include "registry.h"
-#include "emulated.h"
-#include "log.h"
-#include "assert.h"
-
-#define MAXIMUM_CLASS_NAME_LENGTH 32
-#define MAXIMUM_DEVICE_NAME_LENGTH 32
-#define MAXIMUM_ALIAS_LENGTH 128
-
-typedef struct _EMULATED_DEVICE {
- CHAR Class[MAXIMUM_CLASS_NAME_LENGTH];
- CHAR Device[MAXIMUM_DEVICE_NAME_LENGTH];
- CHAR Alias[MAXIMUM_ALIAS_LENGTH];
- BOOLEAN Present;
-} EMULATED_DEVICE, *PEMULATED_DEVICE;
-
-struct _XENFILT_EMULATED_CONTEXT {
- LONG References;
- PEMULATED_DEVICE Table;
-};
-
-#define EMULATED_TAG 'LUME'
-
-static FORCEINLINE PVOID
-__EmulatedAllocate(
- IN ULONG Length
- )
-{
- return __AllocateNonPagedPoolWithTag(Length, EMULATED_TAG);
-}
-
-static FORCEINLINE VOID
-__EmulatedFree(
- IN PVOID Buffer
- )
-{
- __FreePoolWithTag(Buffer, EMULATED_TAG);
-}
-
-static BOOLEAN
-EmulatedIsPresent(
- IN PXENFILT_EMULATED_CONTEXT Context,
- IN PCHAR Class,
- IN PCHAR Device
- )
-{
- PEMULATED_DEVICE Entry;
- BOOLEAN Present;
-
- Present = FALSE;
-
- if (Context->Table == NULL) {
- Warning("no table\n");
- goto done;
- }
-
- for (Entry = Context->Table; strlen(Entry->Alias) != 0; Entry++) {
- if (_stricmp(Entry->Class, Class) == 0 &&
- _stricmp(Entry->Device, Device) == 0)
- break;
- }
-
- if (strlen(Entry->Alias) == 0) {
- Info("%s %s NOT FOUND\n",
- Class,
- Device);
- goto done;
- }
-
- Present = Entry->Present;
-
- Info("%s %s %s\n",
- Entry->Class,
- Entry->Device,
- (Present) ? "PRESENT" : "NOT PRESENT");
-
-done:
- return Present;
-}
-
-static VOID
-EmulatedAcquire(
- IN PXENFILT_EMULATED_CONTEXT Context
- )
-{
- InterlockedIncrement(&Context->References);
-}
-
-static VOID
-EmulatedRelease(
- IN PXENFILT_EMULATED_CONTEXT Context
- )
-{
- ASSERT(Context->References != 0);
- InterlockedDecrement(&Context->References);
-}
-
-#define EMULATED_OPERATION(_Type, _Name, _Arguments) \
- Emulated ## _Name,
-
-static XENFILT_EMULATED_OPERATIONS Operations = {
- DEFINE_EMULATED_OPERATIONS
-};
-
-#undef EMULATED_OPERATION
-
-NTSTATUS
-EmulatedUpdate(
- IN PXENFILT_EMULATED_INTERFACE Interface,
- IN PCHAR Alias
- )
-{
- PXENFILT_EMULATED_CONTEXT Context = Interface->Context;
- PEMULATED_DEVICE Entry;
- HANDLE ServiceKey;
- HANDLE StatusKey;
- LONG Count;
- LONG Index;
- PANSI_STRING Old;
- PANSI_STRING New;
- ULONG Length;
- NTSTATUS status;
-
- if (Context->Table == NULL)
- goto done;
-
- for (Entry = Context->Table; strlen(Entry->Alias) != 0; Entry++) {
- if (strcmp(Entry->Alias, Alias) == 0)
- break;
- }
-
- if (strlen(Entry->Alias) == 0)
- goto done;
-
- Info("%s %s\n", Entry->Class, Entry->Device);
-
- Entry->Present = TRUE;
-
- status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RegistryOpenSubKey(ServiceKey, "Status", KEY_ALL_ACCESS, &StatusKey);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- status = RegistryQuerySzValue(StatusKey, Entry->Class, &Old);
- if (!NT_SUCCESS(status))
- Old = NULL;
-
- Count = 0;
- for (Index = 0; Old != NULL && Old[Index].Buffer != NULL; Index++)
- Count++;
-
- New = __EmulatedAllocate(sizeof (ANSI_STRING) * (Count + 2));
-
- status = STATUS_NO_MEMORY;
- if (New == NULL)
- goto fail3;
-
- for (Index = 0; Index < Count; Index++) {
- Length = Old[Index].Length;
-
- New[Index].MaximumLength = (USHORT)Length + sizeof (CHAR);
- New[Index].Buffer = __EmulatedAllocate(New[Index].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (New[Index].Buffer == NULL)
- goto fail4;
-
- RtlCopyMemory(New[Index].Buffer, Old[Index].Buffer, Length);
- New[Index].Length = (USHORT)Length;
- }
-
- Length = (ULONG)strlen(Entry->Device);
-
- New[Count].MaximumLength = (USHORT)Length + sizeof (CHAR);
- New[Count].Buffer = __EmulatedAllocate(New[Count].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (New[Count].Buffer == NULL)
- goto fail5;
-
- RtlCopyMemory(New[Count].Buffer, Entry->Device, Length);
- New[Count].Length = (USHORT)Length;
-
- status = RegistryUpdateSzValue(StatusKey, Entry->Class, REG_MULTI_SZ, New);
- if (!NT_SUCCESS(status))
- goto fail6;
-
- RegistryFreeSzValue(Old);
-
- for (Index = 0; Index < Count + 1; Index++)
- __EmulatedFree(New[Index].Buffer);
-
- __EmulatedFree(New);
-
- RegistryCloseKey(StatusKey);
-
- RegistryCloseKey(ServiceKey);
-
-done:
- return STATUS_SUCCESS;
-
-fail6:
- Error("fail6\n");
-
- __EmulatedFree(New[Count].Buffer);
-
-fail5:
- Error("fail5\n");
-
- Index = Count;
-
-fail4:
- Error("fail4\n");
-
- while (--Index >= 0)
- __EmulatedFree(New[Index].Buffer);
-
- __EmulatedFree(New);
-
-fail3:
- Error("fail3\n");
-
- RegistryFreeSzValue(Old);
-
- RegistryCloseKey(StatusKey);
-
-fail2:
- Error("fail2\n");
-
- RegistryCloseKey(ServiceKey);
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-static NTSTATUS
-EmulatedCountDevices(
- IN PVOID Context,
- IN HANDLE Key,
- IN PCHAR Name
- )
-{
- PULONG Count = Context;
-
- UNREFERENCED_PARAMETER(Key);
- UNREFERENCED_PARAMETER(Name);
-
- (*Count)++;
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-EmulatedCountClasses(
- IN PVOID Context,
- IN HANDLE Key,
- IN PCHAR Name
- )
-{
- HANDLE ClassKey;
- NTSTATUS status;
-
- status = RegistryOpenSubKey(Key, Name, KEY_ALL_ACCESS, &ClassKey);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RegistryEnumerateValues(ClassKey, EmulatedCountDevices, Context);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- RegistryCloseKey(ClassKey);
-
- return STATUS_SUCCESS;
-
-fail2:
- RegistryCloseKey(ClassKey);
-
-fail1:
- return status;
-}
-
-static NTSTATUS
-EmulatedAddDevices(
- IN PVOID Context,
- IN HANDLE Key,
- IN PCHAR Name
- )
-{
- PEMULATED_DEVICE Entry = *(PEMULATED_DEVICE *)Context;
- PCHAR Class = Entry->Class;
- PANSI_STRING Alias;
- NTSTATUS status;
-
- status = RtlStringCchPrintfA(Entry->Device,
- MAXIMUM_DEVICE_NAME_LENGTH,
- "%s",
- Name);
- ASSERT(NT_SUCCESS(status));
-
- status = RegistryQuerySzValue(Key, Name, &Alias);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RtlStringCchPrintfA(Entry->Alias,
- MAXIMUM_ALIAS_LENGTH,
- "%s",
- Alias[0].Buffer);
- ASSERT(NT_SUCCESS(status));
-
- RegistryFreeSzValue(Alias);
-
- Entry++;
-
- status = RtlStringCchPrintfA(Entry->Class,
- MAXIMUM_CLASS_NAME_LENGTH,
- "%s",
- Class);
- ASSERT(NT_SUCCESS(status));
-
- *(PEMULATED_DEVICE *)Context = Entry;
-
- return STATUS_SUCCESS;
-
-fail1:
- return status;
-}
-
-
-static NTSTATUS
-EmulatedAddClasses(
- IN PVOID Context,
- IN HANDLE Key,
- IN PCHAR Name
- )
-{
- PEMULATED_DEVICE Entry = *(PEMULATED_DEVICE *)Context;
- HANDLE ClassKey;
- NTSTATUS status;
-
- status = RtlStringCchPrintfA(Entry->Class,
- MAXIMUM_CLASS_NAME_LENGTH,
- "%s",
- Name);
- ASSERT(NT_SUCCESS(status));
-
- status = RegistryOpenSubKey(Key, Name, KEY_ALL_ACCESS, &ClassKey);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RegistryEnumerateValues(ClassKey, EmulatedAddDevices, &Entry);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- RegistryCloseKey(ClassKey);
-
- *(PEMULATED_DEVICE *)Context = Entry;
-
- return STATUS_SUCCESS;
-
-fail2:
- RegistryCloseKey(ClassKey);
-
-fail1:
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__EmulatedGetDeviceTable(
- IN PXENFILT_EMULATED_CONTEXT Context
- )
-{
- HANDLE ServiceKey;
- HANDLE AliasesKey;
- ULONG Count;
- PEMULATED_DEVICE Table;
- PEMULATED_DEVICE Entry;
- ULONG Index;
- NTSTATUS status;
-
- status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RegistryOpenSubKey(ServiceKey, "Aliases", KEY_ALL_ACCESS, &AliasesKey);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- Count = 0;
-
- status = RegistryEnumerateSubKeys(AliasesKey, EmulatedCountClasses, &Count);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- Table = NULL;
-
- if (Count == 0)
- goto done;
-
- Table = __EmulatedAllocate(sizeof (EMULATED_DEVICE) * (Count + 1));
-
- status = STATUS_NO_MEMORY;
- if (Table == NULL)
- goto fail4;
-
- Entry = Table;
-
- status = RegistryEnumerateSubKeys(AliasesKey, EmulatedAddClasses, &Entry);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- ASSERT3U((ULONG)(Entry - Table), ==, Count);
- RtlZeroMemory(Entry, sizeof (EMULATED_DEVICE));
-
- for (Index = 0; strlen(Table[Index].Alias) != 0; Index++) {
- Entry = &Table[Index];
-
- Info("[%u]: %s %s -> %s\n",
- Index,
- Entry->Class,
- Entry->Device,
- Entry->Alias);
- }
-
-done:
- Context->Table = Table;
-
- RegistryCloseKey(AliasesKey);
-
- RegistryCloseKey(ServiceKey);
-
- return STATUS_SUCCESS;
-
-fail5:
- Error("fail5\n");
-
- __EmulatedFree(Table);
-
-fail4:
- Error("fail4\n");
-
-fail3:
- Error("fail3\n");
-
- RegistryCloseKey(AliasesKey);
-
-fail2:
- Error("fail2\n");
-
- RegistryCloseKey(ServiceKey);
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-NTSTATUS
-EmulatedInitialize(
- OUT PXENFILT_EMULATED_INTERFACE Interface
- )
-{
- PXENFILT_EMULATED_CONTEXT Context;
- NTSTATUS status;
-
- Trace("====>\n");
-
- Context = __EmulatedAllocate(sizeof (XENFILT_EMULATED_CONTEXT));
-
- status = STATUS_NO_MEMORY;
- if (Context == NULL)
- goto fail1;
-
- status = __EmulatedGetDeviceTable(Context);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- Interface->Context = Context;
- Interface->Operations = &Operations;
-
- Trace("<====\n");
-
- return STATUS_SUCCESS;
-
-fail2:
- Error("fail2\n");
-
- ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT)));
- __EmulatedFree(Context);
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-VOID
-EmulatedTeardown(
- IN OUT PXENFILT_EMULATED_INTERFACE Interface
- )
-{
- PXENFILT_EMULATED_CONTEXT Context = Interface->Context;
-
- Trace("====>\n");
-
- if (Context->Table != NULL) {
- __EmulatedFree(Context->Table);
- Context->Table = NULL;
- }
-
- ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT)));
- __EmulatedFree(Context);
-
- RtlZeroMemory(Interface, sizeof (XENFILT_EMULATED_INTERFACE));
-
- 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 _XENFILT_EMULATED_H
-#define _XENFILT_EMULATED_H
-
-#include <ntddk.h>
-#include <xen.h>
-#include <emulated_interface.h>
-
-struct _XENFILT_EMULATED_INTERFACE {
- PXENFILT_EMULATED_OPERATIONS Operations;
- PXENFILT_EMULATED_CONTEXT Context;
-};
-
-C_ASSERT(FIELD_OFFSET(XENFILT_EMULATED_INTERFACE, Operations) == (ULONG_PTR)EMULATED_OPERATIONS(NULL));
-C_ASSERT(FIELD_OFFSET(XENFILT_EMULATED_INTERFACE, Context) == (ULONG_PTR)EMULATED_CONTEXT(NULL));
-
-extern NTSTATUS
-EmulatedInitialize(
- OUT PXENFILT_EMULATED_INTERFACE Interface
- );
-
-extern NTSTATUS
-EmulatedUpdate(
- IN PXENFILT_EMULATED_INTERFACE Interface,
- IN PCHAR Alias
- );
-
-extern VOID
-EmulatedTeardown(
- IN OUT PXENFILT_EMULATED_INTERFACE Interface
- );
-
-#endif // _XENFILT_EMULATED_H
#include <util.h>
#include <xen.h>
-#include <emulated_interface.h>
-
#include "names.h"
#include "fdo.h"
#include "pdo.h"
#include "driver.h"
#include "registry.h"
#include "mutex.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define FDO_TAG 'ODF'
PIRP DevicePowerIrp;
PANSI_STRING Classes;
- XENFILT_MUTEX Mutex;
+ MUTEX Mutex;
ULONG References;
};
{
ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
- UnplugReplay();
-
__FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
}
__FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
}
-static FORCEINLINE VOID
-__FdoUnplugClass(
- IN HANDLE Key,
- IN PANSI_STRING Class
- )
-{
- PANSI_STRING Classes;
- PANSI_STRING Devices;
- ULONG Index;
- BOOLEAN Match;
- NTSTATUS status;
-
- status = RegistryQuerySzValue(Key, "UnplugClasses", &Classes);
- if (!NT_SUCCESS(status))
- Classes = NULL;
-
- Match = FALSE;
- for (Index = 0; Classes != NULL && Classes[Index].Buffer != NULL; Index++) {
- if (strncmp(Classes[Index].Buffer,
- Class->Buffer,
- Classes[Index].Length) == 0) {
- Match = TRUE;
- break;
- }
- }
-
- RegistryFreeSzValue(Classes);
-
- if (!Match)
- return;
-
- status = RegistryQuerySzValue(Key, Class->Buffer, &Devices);
- if (!NT_SUCCESS(status))
- Devices = NULL;
-
- for (Index = 0; Devices != NULL && Devices[Index].Buffer != NULL; Index++) {
- PANSI_STRING Device = &Devices[Index];
-
- (VOID) UnplugDevice(Class->Buffer, Device->Buffer);
- }
-}
-
-static FORCEINLINE VOID
-__FdoUnplugDevices(
- IN HANDLE Key,
- IN PANSI_STRING Class
- )
-{
- PANSI_STRING Devices;
- ULONG Index;
- NTSTATUS status;
-
- status = RegistryQuerySzValue(Key, "UnplugDevices", &Devices);
- if (!NT_SUCCESS(status))
- Devices = NULL;
-
- for (Index = 0; Devices != NULL && Devices[Index].Buffer != NULL; Index++) {
- PCHAR Device;
-
- Device = strchr(Devices->Buffer, '#');
- if (Device == NULL)
- continue;
-
- *Device++ = '\0';
-
- if (strncmp(Class->Buffer,
- Devices->Buffer,
- Class->Length) != 0)
- continue;
-
- (VOID) UnplugDevice(Class->Buffer, Device);
- }
-}
-
-static FORCEINLINE NTSTATUS
-__FdoUnplugStart(
- IN PXENFILT_FDO Fdo
- )
-{
- HANDLE ServiceKey;
- HANDLE ParametersKey;
- ULONG Index;
- NTSTATUS status;
-
- status = UnplugReference();
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- for (Index = 0; Fdo->Classes != NULL && Fdo->Classes[Index].Buffer != NULL; Index++) {
- PANSI_STRING Class = &Fdo->Classes[Index];
-
- __FdoUnplugClass(ParametersKey, Class);
- __FdoUnplugDevices(ParametersKey, Class);
- }
-
- RegistryCloseKey(ParametersKey);
-
- RegistryCloseKey(ServiceKey);
-
- return STATUS_SUCCESS;
-
-fail3:
- Error("fail3\n");
-
- RegistryCloseKey(ServiceKey);
-
-fail2:
- Error("fail2\n");
-
- UnplugDereference();
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-static FORCEINLINE VOID
-__FdoUnplugStop(
- IN PXENFILT_FDO Fdo
- )
-{
- UNREFERENCED_PARAMETER(Fdo);
-
- UnplugDereference();
-}
-
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
if (!NT_SUCCESS(status))
goto fail1;
- (VOID) __FdoUnplugStart(Fdo);
-
status = FdoForwardIrpSynchronously(Fdo, Irp);
if (!NT_SUCCESS(status))
goto fail2;
return status;
fail2:
- __FdoUnplugStop(Fdo);
-
IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
fail1:
UNREFERENCED_PARAMETER(DeviceObject);
- __FdoUnplugStop(Fdo);
-
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
done:
__FdoSetDevicePnpState(Fdo, Deleted);
- __FdoUnplugStop(Fdo);
-
IoReleaseRemoveLockAndWait(&Fdo->Dx->RemoveLock, Irp);
status = FdoForwardIrpSynchronously(Fdo, Irp);
ObDereferenceObject(LowerDeviceObject);
#pragma prefast(suppress:28197) // Possibly leaking memory 'FilterDeviceObject'
- status = IoCreateDevice(DriverObject,
+ status = IoCreateDevice(DriverGetDriverObject(),
sizeof (XENFILT_DX),
NULL,
DeviceType,
Dx->Fdo = NULL;
- RtlZeroMemory(&Fdo->Mutex, sizeof (XENFILT_MUTEX));
+ RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
if (Fdo->Classes != NULL) {
RegistryFreeSzValue(Fdo->Classes);
#include <ntddk.h>
-#include <emulated_interface.h>
-
#include "types.h"
typedef struct _XENFILT_FDO XENFILT_FDO, *PXENFILT_FDO;
+++ /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 _XENFILT_LOG_H
-#define _XENFILT_LOG_H
-
-#define __MODULE__ "XENFILT"
-
-#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 // _XENFILT_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.
- */
-
-#ifndef _XENFILT_MUTEX_H
-#define _XENFILT_MUTEX_H
-
-#include <ntddk.h>
-
-#include "assert.h"
-
-typedef struct _XENFILT_MUTEX {
- PKTHREAD Owner;
- KEVENT Event;
-} XENFILT_MUTEX, *PXENFILT_MUTEX;
-
-static FORCEINLINE VOID
-InitializeMutex(
- IN PXENFILT_MUTEX Mutex
- )
-{
- RtlZeroMemory(Mutex, sizeof (XENFILT_MUTEX));
-
- KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-AcquireMutex(
- IN PXENFILT_MUTEX Mutex
- )
-{
- (VOID) KeWaitForSingleObject(&Mutex->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
-
- ASSERT3P(Mutex->Owner, ==, NULL);
- Mutex->Owner = KeGetCurrentThread();
-}
-
-static FORCEINLINE VOID
-__drv_maxIRQL(PASSIVE_LEVEL)
-ReleaseMutex(
- IN PXENFILT_MUTEX Mutex
- )
-{
- ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
- Mutex->Owner = NULL;
-
- KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
-}
-
-#endif // _XENFILT_MUTEX_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 _XENFILT_NAMES_H_
-#define _XENFILT_NAMES_H_
-
-#include <ntddk.h>
-
-#include "types.h"
-
-static FORCEINLINE const PCHAR
-PowerTypeName(
- IN POWER_STATE_TYPE Type
- )
-{
-#define _POWER_TYPE_NAME(_Type) \
- case _Type: \
- return #_Type;
-
- switch (Type) {
- _POWER_TYPE_NAME(SystemPowerState);
- _POWER_TYPE_NAME(DevicePowerState);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerSystemStateName(
- IN SYSTEM_POWER_STATE State
- )
-{
-#define _POWER_SYSTEM_STATE_NAME(_State) \
- case PowerSystem ## _State: \
- return #_State;
-
- switch (State) {
- _POWER_SYSTEM_STATE_NAME(Unspecified);
- _POWER_SYSTEM_STATE_NAME(Working);
- _POWER_SYSTEM_STATE_NAME(Sleeping1);
- _POWER_SYSTEM_STATE_NAME(Sleeping2);
- _POWER_SYSTEM_STATE_NAME(Sleeping3);
- _POWER_SYSTEM_STATE_NAME(Hibernate);
- _POWER_SYSTEM_STATE_NAME(Shutdown);
- _POWER_SYSTEM_STATE_NAME(Maximum);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_SYSTEM_STATE_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerDeviceStateName(
- IN DEVICE_POWER_STATE State
- )
-{
-#define _POWER_DEVICE_STATE_NAME(_State) \
- case PowerDevice ## _State: \
- return #_State;
-
- switch (State) {
- _POWER_DEVICE_STATE_NAME(Unspecified);
- _POWER_DEVICE_STATE_NAME(D0);
- _POWER_DEVICE_STATE_NAME(D1);
- _POWER_DEVICE_STATE_NAME(D2);
- _POWER_DEVICE_STATE_NAME(D3);
- _POWER_DEVICE_STATE_NAME(Maximum);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_DEVICE_STATE_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerActionName(
- IN POWER_ACTION Type
- )
-{
-#define _POWER_ACTION_NAME(_Type) \
- case PowerAction ## _Type: \
- return #_Type;
-
- switch (Type) {
- _POWER_ACTION_NAME(None);
- _POWER_ACTION_NAME(Reserved);
- _POWER_ACTION_NAME(Sleep);
- _POWER_ACTION_NAME(Hibernate);
- _POWER_ACTION_NAME(Shutdown);
- _POWER_ACTION_NAME(ShutdownReset);
- _POWER_ACTION_NAME(ShutdownOff);
- _POWER_ACTION_NAME(WarmEject);
- default:
- break;
- }
-
- return ("UNKNOWN");
-#undef _POWER_ACTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PowerMinorFunctionName(
- IN ULONG MinorFunction
- )
-{
-#define _POWER_MINOR_FUNCTION_NAME(_Function) \
- case IRP_MN_ ## _Function: \
- return #_Function;
-
- switch (MinorFunction) {
- _POWER_MINOR_FUNCTION_NAME(WAIT_WAKE);
- _POWER_MINOR_FUNCTION_NAME(POWER_SEQUENCE);
- _POWER_MINOR_FUNCTION_NAME(SET_POWER);
- _POWER_MINOR_FUNCTION_NAME(QUERY_POWER);
-
- default:
- return "UNKNOWN";
- }
-
-#undef _POWER_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-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 PCHAR
-PnpMinorFunctionName(
- IN ULONG Function
- )
-{
-#define _PNP_MINOR_FUNCTION_NAME(_Function) \
- case IRP_MN_ ## _Function: \
- return #_Function;
-
- switch (Function) {
- _PNP_MINOR_FUNCTION_NAME(START_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(CANCEL_REMOVE_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(CANCEL_STOP_DEVICE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_RELATIONS);
- _PNP_MINOR_FUNCTION_NAME(QUERY_INTERFACE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_CAPABILITIES);
- _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCES);
- _PNP_MINOR_FUNCTION_NAME(QUERY_RESOURCE_REQUIREMENTS);
- _PNP_MINOR_FUNCTION_NAME(QUERY_DEVICE_TEXT);
- _PNP_MINOR_FUNCTION_NAME(FILTER_RESOURCE_REQUIREMENTS);
- _PNP_MINOR_FUNCTION_NAME(READ_CONFIG);
- _PNP_MINOR_FUNCTION_NAME(WRITE_CONFIG);
- _PNP_MINOR_FUNCTION_NAME(EJECT);
- _PNP_MINOR_FUNCTION_NAME(SET_LOCK);
- _PNP_MINOR_FUNCTION_NAME(QUERY_ID);
- _PNP_MINOR_FUNCTION_NAME(QUERY_PNP_DEVICE_STATE);
- _PNP_MINOR_FUNCTION_NAME(QUERY_BUS_INFORMATION);
- _PNP_MINOR_FUNCTION_NAME(DEVICE_USAGE_NOTIFICATION);
- _PNP_MINOR_FUNCTION_NAME(SURPRISE_REMOVAL);
- _PNP_MINOR_FUNCTION_NAME(QUERY_LEGACY_BUS_INFORMATION);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _PNP_MINOR_FUNCTION_NAME
-}
-
-static FORCEINLINE const PCHAR
-PartialResourceDescriptorTypeName(
- IN UCHAR Type
- )
-{
-#define _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(_Type) \
- case CmResourceType ## _Type: \
- return #_Type;
-
- switch (Type) {
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Null);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Port);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Interrupt);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Memory);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(Dma);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DeviceSpecific);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(BusNumber);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(MemoryLarge);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(ConfigData);
- _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME(DevicePrivate);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME
-}
-
-#endif // _XENFILT_NAMES_H_
#include "pdo.h"
#include "thread.h"
#include "driver.h"
-#include "emulated.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define PDO_TAG 'ODP'
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
- status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%ws#%ws", DeviceID, InstanceID);
+ status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%ws\\%ws", DeviceID, InstanceID);
ASSERT(NT_SUCCESS(status));
}
return status;
}
-static NTSTATUS
-PdoQueryEmulatedInterface(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- USHORT Size;
- USHORT Version;
- PXENFILT_EMULATED_INTERFACE EmulatedInterface;
- PINTERFACE Interface;
- NTSTATUS status;
-
- UNREFERENCED_PARAMETER(Pdo);
-
- status = Irp->IoStatus.Status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- Size = StackLocation->Parameters.QueryInterface.Size;
- Version = StackLocation->Parameters.QueryInterface.Version;
- Interface = StackLocation->Parameters.QueryInterface.Interface;
-
- if (StackLocation->Parameters.QueryInterface.Version != EMULATED_INTERFACE_VERSION)
- goto done;
-
- status = STATUS_BUFFER_TOO_SMALL;
- if (StackLocation->Parameters.QueryInterface.Size < sizeof (INTERFACE))
- goto done;
-
- EmulatedInterface = DriverGetEmulatedInterface();
-
- Interface->Size = sizeof (INTERFACE);
- Interface->Version = EMULATED_INTERFACE_VERSION;
- Interface->Context = EmulatedInterface;
- Interface->InterfaceReference = NULL;
- Interface->InterfaceDereference = NULL;
-
- Irp->IoStatus.Information = 0;
- status = STATUS_SUCCESS;
-
-done:
- return status;
-}
-
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
{ &GUID_ ## _Guid, #_Guid, (_Function) }
struct _INTERFACE_ENTRY PdoInterfaceTable[] = {
- DEFINE_HANDLER(EMULATED_INTERFACE, PdoQueryEmulatedInterface),
{ NULL, NULL, NULL }
};
PXENFILT_PDO Pdo;
PWCHAR DeviceID;
PWCHAR InstanceID;
- PXENFILT_EMULATED_INTERFACE EmulatedInterface;
NTSTATUS status;
LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
ObDereferenceObject(LowerDeviceObject);
#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
- status = IoCreateDevice(DriverObject,
+ status = IoCreateDevice(DriverGetDriverObject(),
sizeof(XENFILT_DX),
NULL,
DeviceType,
(DeviceID != NULL) ? DeviceID : L"UNKNOWN",
(InstanceID != NULL) ? InstanceID : L"UNKNOWN");
- EmulatedInterface = DriverGetEmulatedInterface();
-
- EMULATED(Acquire, EmulatedInterface);
-
- status = EmulatedUpdate(EmulatedInterface, __PdoGetName(Pdo));
- if (!NT_SUCCESS(status))
- goto fail6;
-
- EMULATED(Release, EmulatedInterface);
-
Info("%p (%s)\n",
FilterDeviceObject,
__PdoGetName(Pdo));
return STATUS_SUCCESS;
-fail6:
- Error("fail6\n");
-
- EMULATED(Release, EmulatedInterface);
-
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
-
fail5:
Error("fail5\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.
- */
-
-#include <ntddk.h>
-#include <util.h>
-
-#include "registry.h"
-#include "log.h"
-#include "assert.h"
-
-#define REGISTRY_POOL 'GERX'
-
-static UNICODE_STRING RegistryPath;
-
-static FORCEINLINE PVOID
-__RegistryAllocate(
- IN ULONG Length
- )
-{
- return __AllocateNonPagedPoolWithTag(Length, REGISTRY_POOL);
-}
-
-static FORCEINLINE VOID
-__RegistryFree(
- IN PVOID Buffer
- )
-{
- __FreePoolWithTag(Buffer, REGISTRY_POOL);
-}
-
-NTSTATUS
-RegistryInitialize(
- IN PUNICODE_STRING Path
- )
-{
- NTSTATUS status;
-
- ASSERT3P(RegistryPath.Buffer, ==, NULL);
-
- status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- return STATUS_SUCCESS;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- return status;
-}
-
-VOID
-RegistryTeardown(
- VOID
- )
-{
- RtlFreeUnicodeString(&RegistryPath);
- RegistryPath.Buffer = NULL;
- RegistryPath.MaximumLength = RegistryPath.Length = 0;
-}
-
-NTSTATUS
-RegistryOpenServiceKey(
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
- )
-{
- OBJECT_ATTRIBUTES Attributes;
- NTSTATUS status;
-
- InitializeObjectAttributes(&Attributes,
- &RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
-
- status = ZwOpenKey(Key,
- DesiredAccess,
- &Attributes);
- if (!NT_SUCCESS(status))
- 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,
- Key,
- NULL);
-
- status = ZwOpenKey(SubKey,
- DesiredAccess,
- &Attributes);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryCreateSubKey(
- IN PHANDLE Key,
- IN PCHAR Name
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- OBJECT_ATTRIBUTES Attributes;
- HANDLE SubKey;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- InitializeObjectAttributes(&Attributes,
- &Unicode,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- Key,
- NULL);
-
- status = ZwCreateKey(&SubKey,
- KEY_ALL_ACCESS,
- &Attributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE,
- NULL
- );
- if (!NT_SUCCESS(status))
- goto fail2;
-
- ZwClose(SubKey);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryDeleteSubKey(
- IN PHANDLE Key,
- IN PCHAR Name
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- OBJECT_ATTRIBUTES Attributes;
- HANDLE SubKey;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- InitializeObjectAttributes(&Attributes,
- &Unicode,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- Key,
- NULL);
-
- status = ZwOpenKey(&SubKey,
- KEY_ALL_ACCESS,
- &Attributes);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- status = ZwDeleteKey(SubKey);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- ZwClose(SubKey);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- ZwClose(SubKey);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryEnumerateSubKeys(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- )
-{
- ULONG Size;
- NTSTATUS status;
- PKEY_FULL_INFORMATION Full;
- PKEY_BASIC_INFORMATION Basic;
- ULONG Index;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail1;
-
- Full = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Full == NULL)
- goto fail2;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- Full,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
- Full->MaxNameLen;
-
- Basic = __RegistryAllocate(Size);
- status = STATUS_NO_MEMORY;
- if (Basic == NULL)
- goto fail4;
-
- for (Index = 0; Index < Full->SubKeys; Index++) {
- UNICODE_STRING Unicode;
- ANSI_STRING Ansi;
-
- status = ZwEnumerateKey(Key,
- Index,
- KeyBasicInformation,
- Basic,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- Unicode.MaximumLength = (USHORT)Basic->NameLength;
- Unicode.Buffer = Basic->Name;
- Unicode.Length = (USHORT)Basic->NameLength;
-
- Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
- Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
-
- status = 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
-RegistryEnumerateValues(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- )
-{
- ULONG Size;
- NTSTATUS status;
- PKEY_FULL_INFORMATION Full;
- PKEY_VALUE_BASIC_INFORMATION Basic;
- ULONG Index;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail1;
-
- Full = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Full == NULL)
- goto fail2;
-
- status = ZwQueryKey(Key,
- KeyFullInformation,
- Full,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
- Full->MaxValueNameLen;
-
- Basic = __RegistryAllocate(Size);
- status = STATUS_NO_MEMORY;
- if (Basic == NULL)
- goto fail4;
-
- for (Index = 0; Index < Full->Values; Index++) {
- UNICODE_STRING Unicode;
- ANSI_STRING Ansi;
-
- status = ZwEnumerateValueKey(Key,
- Index,
- KeyValueBasicInformation,
- Basic,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail5;
-
- Unicode.MaximumLength = (USHORT)Basic->NameLength;
- Unicode.Buffer = Basic->Name;
- Unicode.Length = (USHORT)Basic->NameLength;
-
- Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
- Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
-
- status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
-
- status = Callback(Context, Key, Ansi.Buffer);
-
- __RegistryFree(Ansi.Buffer);
-
- if (!NT_SUCCESS(status))
- goto fail6;
- }
-
- __RegistryFree(Basic);
-
- __RegistryFree(Full);
-
- return STATUS_SUCCESS;
-
-fail6:
-fail5:
- __RegistryFree(Basic);
-
-fail4:
-fail3:
- __RegistryFree(Full);
-
-fail2:
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryQueryDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PULONG Value
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- ULONG Size;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail2;
-
- Partial = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail3;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- Partial,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = STATUS_INVALID_PARAMETER;
- if (Partial->Type != REG_DWORD ||
- Partial->DataLength != sizeof (ULONG))
- goto fail5;
-
- *Value = *(PULONG)Partial->Data;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail5:
-fail4:
- __RegistryFree(Partial);
-
-fail3:
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-NTSTATUS
-RegistryUpdateDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Value
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- sizeof (ULONG));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail2;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_DWORD;
- Partial->DataLength = sizeof (ULONG);
- *(PULONG)Partial->Data = Value;
-
- status = ZwSetValueKey(Key,
- &Unicode,
- Partial->TitleIndex,
- Partial->Type,
- Partial->Data,
- Partial->DataLength);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- __RegistryFree(Partial);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
-
- return status;
-}
-
-static PANSI_STRING
-RegistrySzToAnsi(
- IN PWCHAR Buffer
- )
-{
- PANSI_STRING Ansi;
- ULONG Length;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
-
- status = STATUS_NO_MEMORY;
- if (Ansi == NULL)
- goto fail1;
-
- Length = (ULONG)wcslen(Buffer);
- Ansi[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
- Ansi[0].Buffer = __RegistryAllocate(Ansi[0].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (Ansi[0].Buffer == NULL)
- goto fail2;
-
- RtlInitUnicodeString(&Unicode, Buffer);
- status = RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi[0].Length = (USHORT)Length * sizeof (CHAR);
-
- return Ansi;
-
-fail2:
- __RegistryFree(Ansi);
-
-fail1:
- return NULL;
-}
-
-static PANSI_STRING
-RegistryMultiSzToAnsi(
- IN PWCHAR Buffer
- )
-{
- PANSI_STRING Ansi;
- LONG Index;
- LONG Count;
- NTSTATUS status;
-
- Index = 0;
- Count = 0;
- for (;;) {
- ULONG Length;
-
- Length = (ULONG)wcslen(&Buffer[Index]);
- if (Length == 0)
- break;
-
- Index += Length + 1;
- Count++;
- }
-
- Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
-
- status = STATUS_NO_MEMORY;
- if (Ansi == NULL)
- goto fail1;
-
- for (Index = 0; Index < Count; Index++) {
- ULONG Length;
- UNICODE_STRING Unicode;
-
- Length = (ULONG)wcslen(Buffer);
- Ansi[Index].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
- Ansi[Index].Buffer = __RegistryAllocate(Ansi[Index].MaximumLength);
-
- status = STATUS_NO_MEMORY;
- if (Ansi[Index].Buffer == NULL)
- goto fail2;
-
- RtlInitUnicodeString(&Unicode, Buffer);
-
- status = RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FALSE);
- ASSERT(NT_SUCCESS(status));
-
- Ansi[Index].Length = (USHORT)Length * sizeof (CHAR);
- Buffer += Length + 1;
- }
-
- return Ansi;
-
-fail2:
- while (--Index >= 0)
- __RegistryFree(Ansi[Index].Buffer);
-
- __RegistryFree(Ansi);
-
-fail1:
- return NULL;
-}
-
-NTSTATUS
-RegistryQuerySzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PANSI_STRING *Array
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- PKEY_VALUE_PARTIAL_INFORMATION Value;
- ULONG Size;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- NULL,
- 0,
- &Size);
- if (status != STATUS_BUFFER_TOO_SMALL)
- goto fail2;
-
- Value = __RegistryAllocate(Size);
-
- status = STATUS_NO_MEMORY;
- if (Value == NULL)
- goto fail3;
-
- status = ZwQueryValueKey(Key,
- &Unicode,
- KeyValuePartialInformation,
- Value,
- Size,
- &Size);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- switch (Value->Type) {
- case REG_SZ:
- status = STATUS_NO_MEMORY;
- *Array = RegistrySzToAnsi((PWCHAR)Value->Data);
- break;
-
- case REG_MULTI_SZ:
- status = STATUS_NO_MEMORY;
- *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data);
- break;
-
- default:
- status = STATUS_INVALID_PARAMETER;
- *Array = NULL;
- break;
- }
-
- if (*Array == NULL)
- goto fail5;
-
- __RegistryFree(Value);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail5:
-fail4:
- __RegistryFree(Value);
-
-fail3:
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToSz(
- PANSI_STRING Ansi
- )
-{
- ULONG Length;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Length = Ansi->Length + 1;
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- Length * sizeof (WCHAR));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail1;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_SZ;
- Partial->DataLength = Length * sizeof (WCHAR);
-
- Unicode.MaximumLength = (UCHAR)Partial->DataLength;
- Unicode.Buffer = (PWCHAR)Partial->Data;
- Unicode.Length = 0;
-
- status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- return Partial;
-
-fail2:
- __RegistryFree(Partial);
-
-fail1:
- return NULL;
-}
-
-static PKEY_VALUE_PARTIAL_INFORMATION
-RegistryAnsiToMultiSz(
- PANSI_STRING Ansi
- )
-{
- ULONG Length;
- ULONG Index;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- UNICODE_STRING Unicode;
- NTSTATUS status;
-
- Length = 1;
- for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
- Length += Ansi[Index].Length + 1;
-
- Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
- Length * sizeof (WCHAR));
-
- status = STATUS_NO_MEMORY;
- if (Partial == NULL)
- goto fail1;
-
- Partial->TitleIndex = 0;
- Partial->Type = REG_MULTI_SZ;
- Partial->DataLength = Length * sizeof (WCHAR);
-
- Unicode.MaximumLength = (USHORT)Partial->DataLength;
- Unicode.Buffer = (PWCHAR)Partial->Data;
- Unicode.Length = 0;
-
- for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
- if (!NT_SUCCESS(status))
- goto fail2;
-
- Length = Unicode.Length / sizeof (WCHAR);
-
- ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
- Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
- Unicode.Buffer += Length + 1;
- Unicode.Length = 0;
- }
- *Unicode.Buffer = L'\0';
-
- return Partial;
-
-fail2:
- __RegistryFree(Partial);
-
-fail1:
- return NULL;
-}
-
-NTSTATUS
-RegistryUpdateSzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Type,
- ...
- )
-{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
- va_list Arguments;
- PKEY_VALUE_PARTIAL_INFORMATION Partial;
- NTSTATUS status;
-
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- va_start(Arguments, Type);
- switch (Type) {
- case REG_SZ: {
- PANSI_STRING Argument;
-
- Argument = va_arg(Arguments, PANSI_STRING);
-
- status = STATUS_NO_MEMORY;
- Partial = RegistryAnsiToSz(Argument);
- break;
- }
- case REG_MULTI_SZ: {
- PANSI_STRING Argument;
-
- Argument = va_arg(Arguments, PANSI_STRING);
-
- status = STATUS_NO_MEMORY;
- Partial = RegistryAnsiToMultiSz(Argument);
- break;
- }
- default:
- status = STATUS_INVALID_PARAMETER;
- Partial = NULL;
- break;
- }
- va_end(Arguments);
-
- if (Partial == NULL)
- goto fail2;
-
- status = ZwSetValueKey(Key,
- &Unicode,
- Partial->TitleIndex,
- Partial->Type,
- Partial->Data,
- Partial->DataLength);
- if (!NT_SUCCESS(status))
- goto fail3;
-
- __RegistryFree(Partial);
-
- RtlFreeUnicodeString(&Unicode);
-
- return STATUS_SUCCESS;
-
-fail3:
- __RegistryFree(Partial);
-
-fail2:
- RtlFreeUnicodeString(&Unicode);
-
-fail1:
- return status;
-}
-
-VOID
-RegistryFreeSzValue(
- IN PANSI_STRING Array
- )
-{
- ULONG Index;
-
- if (Array == NULL)
- return;
-
- for (Index = 0; Array[Index].Buffer != NULL; Index++)
- __RegistryFree(Array[Index].Buffer);
-
- __RegistryFree(Array);
-}
-
-VOID
-RegistryCloseKey(
- IN HANDLE Key
- )
-{
- ZwClose(Key);
-}
+++ /dev/null
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _XENFILT_REGISTRY_H
-#define _XENFILT_REGISTRY_H
-
-#include <ntddk.h>
-
-extern NTSTATUS
-RegistryInitialize(
- IN PUNICODE_STRING Path
- );
-
-extern VOID
-RegistryTeardown(
- 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 SubKey
- );
-
-extern NTSTATUS
-RegistryCreateSubKey(
- IN HANDLE Key,
- IN PCHAR Name
- );
-
-extern NTSTATUS
-RegistryDeleteSubKey(
- IN HANDLE Key,
- IN PCHAR Name
- );
-
-extern NTSTATUS
-RegistryEnumerateSubKeys(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- );
-
-extern NTSTATUS
-RegistryEnumerateValues(
- IN HANDLE Key,
- IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
- IN PVOID Context
- );
-
-extern NTSTATUS
-RegistryQueryDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PULONG Value
- );
-
-extern NTSTATUS
-RegistryUpdateDwordValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Value
- );
-
-extern NTSTATUS
-RegistryQuerySzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- OUT PANSI_STRING *Array
- );
-
-extern VOID
-RegistryFreeSzValue(
- IN PANSI_STRING Array
- );
-
-extern NTSTATUS
-RegistryUpdateSzValue(
- IN HANDLE Key,
- IN PCHAR Name,
- IN ULONG Type,
- ...
- );
-
-extern VOID
-RegistryCloseKey(
- IN HANDLE Key
- );
-
-#endif // _XENFILT_REGISTRY_H
#include <util.h>
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define THREAD_POOL 'ERHT'