--- /dev/null
+7.0.0 (2013-05-30):
+* Initial public release
+
+7.1.0 (2013-07-08):
+* New 'bottom layer' of code which can be open sourced.
+* Upped version number to reflect build number reset
--- /dev/null
+To install the XenServer Interface Device Driver onto a XenServer Windows
+guest VM:
+
+* Copy xeniface.sys and xeniface.inf onto the guest VM
+* Install xenbus.sys on the guest VM
+* Copy dpinst.exe from the Windows driver kit into the same folder as
+ xeniface.sys and xeniface.inf on the guest vm, ensuring the version
+ of dpinst.exe matches the architecture of the verison of Windows
+ installed on your VM
+* As administrator, run dpinst.exe on the guest vm
+* If any warnings arise about unknown certificates, accept them
+
--- /dev/null
+List of maintainers and how to submit changes
+=============================================
+
+This is an early public release of the XenServer XenIface driver.
+
+At the moment we are working hard on improving this early release, to make
+it easier to build and install and test on your own systems. As such things
+are in a state of flux, and we may well find it difficult to take submissions.
+
+We hope things will have improved by January 2014
+
+If you do wish to submit code, we recommend reaching out to the maintainers
+first, who will attempt to steer you in the right direction.
+
+We also request you follow these guidelines:
+
+1. All submissions must be made under the terms of the "Developer's Certificate
+ of Origin" (DC) and should include a Signed-off-by: line.
+
+2. All Submissions should use Unix line endings for consitency with the rest of
+ the XenServer project
+
+3. Each patch should include a descriptive commit comment that helps understand
+ why the patch is necessary and why it works. This will be used both for
+ initial review and for new people to understand how the code works later
+
+4. Make sure you have the right to submit any changes you make. If you do
+ changes at work you may find your employer owns the patches instead of
+ you.
+
+
+Maintainers List
+----------------
+
+* Ben Chalmers <ben.chalmers@citrix.com>
+
+* Paul Durrant <paul.durrant@citrix.com>
+
+* Owen Smith <owen.smith@citrix.com>
+
--- /dev/null
+XenIface - The XenServer Interface Device Driver
+==========================================
+
+XenIface is a device driver which provides userlevel applications WMI and Ioctl
+read and write access to information provided to the guest domain by
+xenstore and xapi
+
+Quick Start
+===========
+
+Prerequisites to build
+----------------------
+
+* Visual Studio 2012 or later
+* Windows Driver Kit 8 or later
+* Python 3 or later
+
+Environment variables used in building driver
+-----------------------------
+
+MAJOR\_VERSION Major version number
+
+MINOR\_VERSION Minor version number
+
+MICRO\_VERSION Micro version number
+
+BUILD\_NUMBER Build number
+
+SYMBOL\_SERVER location of a writable symbol server directory
+
+KIT location of the Windows driver kit
+
+PROCESSOR\_ARCHITECTURE x86 or x64
+
+VS location of visual studio
+
+Commands to build
+-----------------
+
+ git clone http://github.com/xenserver/win-xeniface
+ cd win-xeniface
+ .\\build.py [checked | free]
+
+
+Device tree diagram
+-------------------
+
+ XenIface
+ |
+ XenBus
+ |
+ PCI Bus
+
+See Also
+========
+
+win-xeniface\WmiDocumentation.txt for documentation of the WMI interface
+
if __name__ == '__main__':
os.environ['MAJOR_VERSION'] = '7'
- os.environ['MINOR_VERSION'] = '0'
+ os.environ['MINOR_VERSION'] = '1'
os.environ['MICRO_VERSION'] = '0'
if 'BUILD_NUMBER' not in os.environ.keys():
- listfile = callfnout(['hg','manifest'])
+ listfile = callfnout(['git','ls-tree', '-r', '--name-only', 'HEAD'])
archive('xeniface\\source.tgz', listfile.splitlines(), tgz=True)
archive('xeniface.tar', ['xeniface', 'revision'])
--- /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 = (PUCHAR)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 = (PUCHAR)_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);
+}
+
+#endif // _UTIL_H
+++ /dev/null
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms,
- * with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-
-#define MAJOR_VERSION 7
-#define MAJOR_VERSION_STR "7"
-
-#define MINOR_VERSION 0
-#define MINOR_VERSION_STR "0"
-
-#define MICRO_VERSION 0
-#define MICRO_VERSION_STR "0"
-
-#define BUILD_NUMBER 0
-#define BUILD_NUMBER_STR "0"
-
-#define YEAR 2013
-#define YEAR_STR "2013"
-#define MONTH 3
-#define MONTH_STR "3"
-#define DAY 25
-#define DAY_STR "25"
--- /dev/null
+#!python -u
+
+import os, sys
+import subprocess
+import glob
+from pprint import pprint
+
+def regenerate_kdfiles(filename, arch, pkg, source):
+ cwd = os.getcwd()
+ file = open(filename, 'w')
+ os.chdir(pkg + '/' + arch)
+ drivers = glob.glob('*.sys')
+ pprint(drivers)
+ for driver in drivers:
+ file.write("map\n")
+ file.write('\SystemRoot\System32\drivers\\' + driver + '\n')
+ file.write(source + '\\' + pkg + '\\' + arch + '\\' + driver + '\n')
+ file.write('\n')
+ os.chdir(cwd)
+ file.close()
+
+if __name__ == '__main__':
+ pkg = 'xeniface'
+ source = os.getcwd()
+ regenerate_kdfiles('kdfiles32.txt', 'x86', pkg, source)
+ regenerate_kdfiles('kdfiles64.txt', 'x64', pkg, source)
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <SignMode>ProductionSign</SignMode>\r
+ <ProductionCertificate>CN="Citrix Systems, Inc.", OU=Digital ID Class 3 - Microsoft Software Validation v2, O="Citrix Systems, Inc.", L=Santa Clara, S=California, C=US | 9505C081954CC0A3E8B904458ACACD72EABD98B5</ProductionCertificate>\r
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>\r
+ </PropertyGroup>\r
+</Project>
\ No newline at end of file
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
- <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
- <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+ <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="../../src/xeniface/ioctls.c" />
- <ClCompile Include="../../src/xeniface/power.c" />
<ClCompile Include="../../src/xeniface/wmi.c" />
- <ClCompile Include="../../src/xeniface/xeniface.c" />
+ <ClCompile Include="..\..\src\xeniface\driver.c" />
+ <ClCompile Include="..\..\src\xeniface\fdo.c" />
+ <ClCompile Include="..\..\src\xeniface\thread.c" />
</ItemGroup>
<ItemGroup>
<Mofcomp Include="../../src/xeniface/wmi.mof">
- <CreateBinaryMofFile>$(IntDir)/wmi.bmf</CreateBinaryMofFile>
+ <CreateBinaryMofFile>$(IntDir)/wmi.bmf</CreateBinaryMofFile>
</Mofcomp>
</ItemGroup>
<ItemGroup>
<ItemGroup>
<None Include="..\package\package.vcxproj" />
</ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\include\util.h" />
+ <ClInclude Include="..\..\src\xeniface\assert.h" />
+ <ClInclude Include="..\..\src\xeniface\driver.h" />
+ <ClInclude Include="..\..\src\xeniface\fdo.h" />
+ <ClInclude Include="..\..\src\xeniface\ioctls.h" />
+ <ClInclude Include="..\..\src\xeniface\log.h" />
+ <ClInclude Include="..\..\src\xeniface\mutex.h" />
+ <ClInclude Include="..\..\src\xeniface\names.h" />
+ <ClInclude Include="..\..\src\xeniface\thread.h" />
+ <ClInclude Include="..\..\src\xeniface\types.h" />
+ <ClInclude Include="..\..\src\xeniface\wmi.h" />
+ </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
- <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <PropertyGroup>\r
+ <SignMode>ProductionSign</SignMode>\r
+ <ProductionCertificate>CN="Citrix Systems, Inc.", OU=Digital ID Class 3 - Microsoft Software Validation v2, O="Citrix Systems, Inc.", L=Santa Clara, S=California, C=US | 9505C081954CC0A3E8B904458ACACD72EABD98B5</ProductionCertificate>\r
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>\r
+ </PropertyGroup>\r
+</Project>
\ No newline at end of file
-; 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.
-
-[Version]
-Signature="$WINDOWS NT$"
-Class=System
-ClassGUID={4d36e97d-e325-11ce-bfc1-08002be10318}
-Provider=%Citrix%
-DriverVer=09/07/2011,6.0.0.0
-CatalogFile=xeniface.cat
-
-[DestinationDirs]
-DefaultDestDir = 12
-
-;*****************************************
-; Xeniface Device Install Section
-;*****************************************
-
-[Manufacturer]
-%Citrix%=Citrix,NT$ARCH$
-
-[Citrix.NT$ARCH$]
-; DisplayName Section DeviceId
-; ----------- ------- --------
-%XenIfaceDevice.DeviceDesc%=XenIface_Device, XENBUS\CLASS_IFACE&REV_02
-
-[XenIface_Device.NT$ARCH$]
-CopyFiles=XenIface_Device.NT.Copy
-
-[XenIFace_Device.NT.Copy]
-xeniface.sys
-
-;-------------- Service installation
-
-[Xeniface_Device.NT$ARCH$.Services]
-AddService = xeniface, %SPSVCINST_ASSOCSERVICE%, xeniface_Service_Inst
-
-[xeniface_Service_Inst]
-DisplayName = %xeniface.SVCDESC%
-ServiceType = 1 ; SERVICE_KERNEL_DRIVER
-StartType = 3 ; SERVICE_DEMAND_START
-ErrorControl = 1 ; SERVICE_ERROR_NORMAL
-ServiceBinary = %12%\xeniface.sys
-LoadOrderGroup = Extended Base
-
-
-[SourceDisksNames]
-1 = %DiskId1%,,,""
-
-[SourceDisksFiles]
-xeniface.sys = 1,,
-
-[Strings]
-SPSVCINST_ASSOCSERVICE= 0x00000002
-Citrix= "Citrix Systems, Inc."
-ClassName = "XenIface"
-DiskId1 = "Citrix Tools for Virtual Machines"
-XenIfaceDevice.DeviceDesc = "Citrix Xen Interface"
-xeniface.SVCDESC = "Citrix Xen Interface Device Driver"
-
+; Copyright (c) Citrix Systems Inc.\r
+; All rights reserved.\r
+;\r
+; Redistribution and use in source and binary forms, \r
+; with or without modification, are permitted provided \r
+; that the following conditions are met:\r
+;\r
+; * Redistributions of source code must retain the above \r
+; copyright notice, this list of conditions and the \r
+; following disclaimer.\r
+; * Redistributions in binary form must reproduce the above \r
+; copyright notice, this list of conditions and the \r
+; following disclaimer in the documentation and/or other \r
+; materials provided with the distribution.\r
+;\r
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
+; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, \r
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF \r
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
+; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR \r
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \r
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
+; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING \r
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \r
+; SUCH DAMAGE.\r
+\r
+[Version]\r
+Signature="$WINDOWS NT$"\r
+Class=System\r
+ClassGUID={4d36e97d-e325-11ce-bfc1-08002be10318} \r
+Provider=%Citrix%\r
+DriverVer=09/07/2011,6.0.0.0\r
+CatalogFile=xeniface.cat\r
+\r
+[DestinationDirs]\r
+DefaultDestDir = 12\r
+\r
+;*****************************************\r
+; Xeniface Device Install Section\r
+;*****************************************\r
+\r
+[Manufacturer]\r
+%Citrix%=Citrix,NT$ARCH$\r
+\r
+[Citrix.NT$ARCH$]\r
+; DisplayName Section DeviceId\r
+; ----------- ------- --------\r
+%XenIfaceDevice.DeviceDesc%=XenIface_Device, XENBUS\CLASS_IFACE&REV_02\r
+\r
+[XenIface_Device.NT$ARCH$]\r
+CopyFiles=XenIface_Device.NT.Copy\r
+\r
+[XenIFace_Device.NT.Copy]\r
+xeniface.sys\r
+\r
+;-------------- Service installation\r
+\r
+[Xeniface_Device.NT$ARCH$.Services]\r
+AddService = xeniface, %SPSVCINST_ASSOCSERVICE%, xeniface_Service_Inst\r
+\r
+[xeniface_Service_Inst]\r
+DisplayName = %xeniface.SVCDESC%\r
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER\r
+StartType = 3 ; SERVICE_DEMAND_START \r
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL\r
+ServiceBinary = %12%\xeniface.sys\r
+LoadOrderGroup = Extended Base\r
+\r
+\r
+[SourceDisksNames]\r
+1 = %DiskId1%,,,""\r
+\r
+[SourceDisksFiles]\r
+xeniface.sys = 1,,\r
+\r
+[Strings]\r
+SPSVCINST_ASSOCSERVICE= 0x00000002\r
+Citrix= "Citrix Systems, Inc." \r
+ClassName = "XenIface"\r
+DiskId1 = "Citrix Tools for Virtual Machines"\r
+XenIfaceDevice.DeviceDesc = "Citrix Xen Interface"\r
+xeniface.SVCDESC = "Citrix Xen Interface Device Driver"\r
+\r
--- /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 _XENIFACE_ASSERT_H
+#define _XENIFACE_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 // _XENIFACE_ASSERT_H
+
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+//#include <util.h>
+#include <version.h>
+
+#include "fdo.h"
+#include "driver.h"
+
+#include "assert.h"
+#include "wmi.h"
+extern PULONG InitSafeBootMode;
+
+PDRIVER_OBJECT DriverObject;
+
+DRIVER_UNLOAD DriverUnload;
+
+XENIFACE_PARAMETERS DriverParameters;
+
+VOID
+DriverUnload(
+ IN PDRIVER_OBJECT _DriverObject
+ )
+{
+ ASSERT3P(_DriverObject, ==, DriverObject);
+
+ Trace("====>\n");
+
+ if (*InitSafeBootMode > 0)
+ goto done;
+
+
+ if (DriverParameters.RegistryPath.Buffer != NULL) {
+ ExFreePool(DriverParameters.RegistryPath.Buffer);
+ }
+
+done:
+ DriverObject = NULL;
+
+ Trace("<====\n");
+}
+
+DRIVER_ADD_DEVICE AddDevice;
+
+NTSTATUS
+AddDevice(
+ IN PDRIVER_OBJECT _DriverObject,
+ IN PDEVICE_OBJECT DeviceObject
+ )
+{
+ NTSTATUS status;
+
+ ASSERT3P(_DriverObject, ==, DriverObject);
+
+ status = FdoCreate(DeviceObject);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ // prefast stupidity
+ ASSERT(!(DeviceObject->Flags & DO_DEVICE_INITIALIZING));
+ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+DRIVER_DISPATCH Dispatch;
+
+NTSTATUS
+Dispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ PXENIFACE_DX Dx;
+ NTSTATUS status;
+
+ Dx = (PXENIFACE_DX)DeviceObject->DeviceExtension;
+ ASSERT3P(Dx->DeviceObject, ==, DeviceObject);
+
+ if (Dx->DevicePnpState == Deleted) {
+ status = STATUS_NO_SUCH_DEVICE;
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ goto done;
+ }
+
+ status = STATUS_NOT_SUPPORTED;
+ switch (Dx->Type) {
+ case FUNCTION_DEVICE_OBJECT: {
+ PXENIFACE_FDO Fdo = Dx->Fdo;
+
+ status = FdoDispatch(Fdo, Irp);
+ break;
+ }
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+
+done:
+ return status;
+}
+
+DRIVER_INITIALIZE DriverEntry;
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT _DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ ULONG Index;
+ NTSTATUS status = STATUS_UNSUCCESSFUL;
+ ASSERT3P(DriverObject, ==, NULL);
+
+ ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+
+ Trace("====>\n");
+
+ Info("%s (%s)\n",
+ MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+ DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+ DriverParameters.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
+ DriverParameters.RegistryPath.Length = RegistryPath->Length;
+ DriverParameters.RegistryPath.Buffer = ExAllocatePoolWithTag (PagedPool,
+ DriverParameters.RegistryPath.MaximumLength,
+ XENIFACE_POOL_TAG);
+ if (NULL == DriverParameters.RegistryPath.Buffer) {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto fail1;
+ }
+ RtlCopyUnicodeString(&DriverParameters.RegistryPath, RegistryPath);
+
+
+ DriverObject = _DriverObject;
+ DriverObject->DriverUnload = DriverUnload;
+
+ if (*InitSafeBootMode > 0)
+ goto done;
+
+ DriverObject->DriverExtension->AddDevice = AddDevice;
+
+ for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) {
+#pragma prefast(suppress:28169) // No __drv_dispatchType annotation
+#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation for IRP_MJ_CREATE
+ DriverObject->MajorFunction[Index] = Dispatch;
+ }
+
+done:
+ Trace("<====\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 _XENIFACE_DRIVER_H
+#define _XENIFACE_DRIVER_H
+
+
+
+#include "fdo.h"
+#include "types.h"
+#include "thread.h"
+#include "mutex.h"
+#define NTSTRSAFE_LIB
+#include <ntstrsafe.h>
+
+#pragma warning(disable:4100 4057)
+
+#include <wmilib.h>
+#include <ntddk.h>
+extern PDRIVER_OBJECT DriverObject;
+
+
+#define MAX_DEVICE_ID_LEN 200
+
+typedef struct _XENIFACE_PARAMETERS {
+ UNICODE_STRING RegistryPath;
+
+} XENIFACE_PARAMETERS, *PXENIFACE_PARAMETERS;
+
+#define XENIFACE_POOL_TAG (ULONG) 'XIfc'
+
+extern XENIFACE_PARAMETERS DriverParameters;
+
+typedef struct _XENIFACE_DX {
+ PDEVICE_OBJECT DeviceObject;
+ DEVICE_OBJECT_TYPE Type;
+
+ DEVICE_PNP_STATE DevicePnpState;
+ DEVICE_PNP_STATE PreviousDevicePnpState;
+
+ SYSTEM_POWER_STATE SystemPowerState;
+ DEVICE_POWER_STATE DevicePowerState;
+
+ CHAR Name[MAX_DEVICE_ID_LEN];
+
+ LIST_ENTRY ListEntry;
+
+ struct _XENIFACE_FDO *Fdo;
+
+} XENIFACE_DX, *PXENIFACE_DX;
+
+
+#endif // _XENIFACE_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 <wdmguid.h>
+#include <ntstrsafe.h>
+#include <stdlib.h>
+
+#include <store_interface.h>
+
+#include <suspend_interface.h>
+
+
+#include "driver.h"
+#include "fdo.h"
+#include "thread.h"
+#include "mutex.h"
+#include "log.h"
+#include "assert.h"
+#include "util.h"
+#include "names.h"
+#include "ioctls.h"
+#include "wmi.h"
+#include "xeniface_ioctls.h"
+
+#define FDO_POOL 'ODF'
+
+#define MAXNAMELEN 128
+
+
+static void
+FdoInitialiseXSRegistryEntries(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ OBJECT_ATTRIBUTES Attributes;
+ HANDLE RegHandle;
+ UNICODE_STRING UnicodeValueName;
+ UNICODE_STRING UnicodeValue;
+ ANSI_STRING AnsiValue;
+ char *value;
+ NTSTATUS status;
+ NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ status = STORE(Read, Fdo->StoreInterface, NULL, NULL, "/mh/boot-time/management-mac-address", &value);
+ if (!NT_SUCCESS(status)){
+ XenIfaceDebugPrint(ERROR, "no such xenstore key\n");
+ goto failXS;
+ }
+
+ InitializeObjectAttributes(&Attributes, &DriverParameters.RegistryPath,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ status = ZwOpenKey(&RegHandle, KEY_WRITE, &Attributes);
+
+ if (!NT_SUCCESS(status)) {
+ XenIfaceDebugPrint(ERROR, "no such registry key %s\n", DriverParameters.RegistryPath);
+ goto failReg;
+ }
+
+ RtlInitUnicodeString(&UnicodeValueName, L"MgmtMacAddr");
+ RtlInitUnicodeString(&UnicodeValue, NULL);
+ RtlInitAnsiString(&AnsiValue, value);
+
+ XenIfaceDebugPrint(ERROR, "About to convert unicode string\n");
+ status = RtlAnsiStringToUnicodeString(&UnicodeValue, &AnsiValue, TRUE);
+ if (!NT_SUCCESS(status)) {
+ XenIfaceDebugPrint(ERROR, "Can't convert string\n");
+ goto failReg;
+ }
+
+ XenIfaceDebugPrint(ERROR, "About to write unicode string\n");
+ status = ZwSetValueKey(RegHandle, &UnicodeValueName, 0, REG_SZ, UnicodeValue.Buffer, UnicodeValue.Length+sizeof(WCHAR));
+ if (!NT_SUCCESS(status)) {
+ XenIfaceDebugPrint(ERROR, "Can't write key\n");
+ goto failWrite;
+ }
+
+ ZwClose(RegHandle);
+
+ RtlFreeUnicodeString(&UnicodeValue);
+ STORE(Free, Fdo->StoreInterface, value);
+
+ return;
+
+failWrite:
+
+ XenIfaceDebugPrint(ERROR, "Fail : Write\n");
+ ZwClose(RegHandle);
+ RtlFreeUnicodeString(&UnicodeValue);
+
+failReg:
+
+ XenIfaceDebugPrint(ERROR, "Fail : Reg\n");
+ STORE(Free, Fdo->StoreInterface, value);
+failXS:
+ XenIfaceDebugPrint(ERROR, "Failed to initialise registry (%08x)\n", status);
+ return;
+}
+
+
+#define REGISTRY_WRITE_EVENT 0
+#define REGISTRY_THREAD_END_EVENT 1
+#define REGISTRY_EVENTS 2
+
+static NTSTATUS FdoRegistryThreadHandler(IN PXENIFACE_THREAD Self,
+ IN PVOID StartContext) {
+ KEVENT* threadevents[REGISTRY_EVENTS];
+ PXENIFACE_FDO Fdo = (PXENIFACE_FDO)StartContext;
+ NTSTATUS status;
+
+ PKEVENT Event;
+
+ Event = ThreadGetEvent(Self);
+
+ threadevents[REGISTRY_WRITE_EVENT] = &Fdo->registryWriteEvent;
+ threadevents[REGISTRY_THREAD_END_EVENT] = Event;
+
+ for(;;) {
+
+ status = KeWaitForMultipleObjects(REGISTRY_EVENTS, (PVOID *)threadevents, WaitAny, Executive, KernelMode, TRUE, NULL, NULL);
+ if ((status>=STATUS_WAIT_0) && (status < STATUS_WAIT_0+REGISTRY_EVENTS)) {
+ if (status == STATUS_WAIT_0+REGISTRY_WRITE_EVENT) {
+ if (Fdo->StoreInterface) {
+ XenIfaceDebugPrint(ERROR,"WriteRegistry\n");
+ FdoInitialiseXSRegistryEntries(Fdo);
+ KeClearEvent(threadevents[REGISTRY_WRITE_EVENT]);
+ }
+ }
+ if (status == STATUS_WAIT_0+REGISTRY_THREAD_END_EVENT) {
+ if (ThreadIsAlerted(Self))
+ return STATUS_SUCCESS;
+ KeClearEvent(threadevents[REGISTRY_THREAD_END_EVENT]);
+ }
+
+ }
+ else if (!NT_SUCCESS(status)) {
+ XenIfaceDebugPrint(ERROR, "Registry handler thread failed %x\n", status);
+ return status;
+ }
+ }
+
+}
+
+
+
+static FORCEINLINE PVOID
+__FdoAllocate(
+ IN ULONG Length
+ )
+{
+ return __AllocateNonPagedPoolWithTag(Length, FDO_POOL);
+}
+
+static FORCEINLINE VOID
+__FdoFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, FDO_POOL);
+}
+
+static FORCEINLINE VOID
+__FdoSetDevicePnpState(
+ IN PXENIFACE_FDO Fdo,
+ IN DEVICE_PNP_STATE State
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ // We can never transition out of the deleted state
+ ASSERT(Dx->DevicePnpState != Deleted || State == Deleted);
+
+ Dx->PreviousDevicePnpState = Dx->DevicePnpState;
+ Dx->DevicePnpState = State;
+}
+
+static FORCEINLINE VOID
+__FdoRestoreDevicePnpState(
+ IN PXENIFACE_FDO Fdo,
+ IN DEVICE_PNP_STATE State
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ if (Dx->DevicePnpState == State)
+ Dx->DevicePnpState = Dx->PreviousDevicePnpState;
+}
+
+static FORCEINLINE DEVICE_PNP_STATE
+__FdoGetDevicePnpState(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ return Dx->DevicePnpState;
+}
+
+static FORCEINLINE VOID
+__FdoSetDevicePowerState(
+ IN PXENIFACE_FDO Fdo,
+ IN DEVICE_POWER_STATE State
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ Dx->DevicePowerState = State;
+}
+
+static FORCEINLINE DEVICE_POWER_STATE
+__FdoGetDevicePowerState(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ return Dx->DevicePowerState;
+}
+
+static FORCEINLINE VOID
+__FdoSetSystemPowerState(
+ IN PXENIFACE_FDO Fdo,
+ IN SYSTEM_POWER_STATE State
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ Dx->SystemPowerState = State;
+}
+
+static FORCEINLINE SYSTEM_POWER_STATE
+__FdoGetSystemPowerState(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ return Dx->SystemPowerState;
+}
+
+static FORCEINLINE PDEVICE_OBJECT
+__FdoGetPhysicalDeviceObject(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ return Fdo->PhysicalDeviceObject;
+}
+
+PDEVICE_OBJECT
+FdoGetPhysicalDeviceObject(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ return __FdoGetPhysicalDeviceObject(Fdo);
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetName(
+ IN PXENIFACE_FDO Fdo,
+ IN PWCHAR Name
+ )
+{
+ PXENIFACE_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 = 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] = '_';
+ }
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+static FORCEINLINE PCHAR
+__FdoGetName(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+
+ return Dx->Name;
+}
+
+PCHAR
+FdoGetName(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ return __FdoGetName(Fdo);
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+__FdoDelegateIrp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PKEVENT Event = (PKEVENT)Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+FdoDelegateIrp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PDEVICE_OBJECT DeviceObject;
+ PIO_STACK_LOCATION StackLocation;
+ PIRP SubIrp;
+ KEVENT Event;
+ PIO_STACK_LOCATION SubStackLocation;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+ // Find the top of the FDO stack and hold a reference
+ DeviceObject = IoGetAttachedDeviceReference(Fdo->Dx->DeviceObject);
+
+ // Get a new IRP for the FDO stack
+ SubIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
+
+ status = STATUS_NO_MEMORY;
+ if (SubIrp == NULL)
+ goto done;
+
+ // Copy in the information from the original IRP
+ SubStackLocation = IoGetNextIrpStackLocation(SubIrp);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ RtlCopyMemory(SubStackLocation, StackLocation,
+ FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine));
+ SubStackLocation->Control = 0;
+
+ IoSetCompletionRoutine(SubIrp,
+ __FdoDelegateIrp,
+ &Event,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ // Default completion status
+ SubIrp->IoStatus.Status = Irp->IoStatus.Status;
+
+ status = IoCallDriver(DeviceObject, SubIrp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = SubIrp->IoStatus.Status;
+ } else {
+ ASSERT3U(status, ==, SubIrp->IoStatus.Status);
+ }
+
+ IoFreeIrp(SubIrp);
+
+done:
+ ObDereferenceObject(DeviceObject);
+
+ return status;
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+__FdoForwardIrpSynchronously(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PKEVENT Event = (PKEVENT)Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Irp);
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static NTSTATUS
+FdoForwardIrpSynchronously(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ KEVENT Event;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ __FdoForwardIrpSynchronously,
+ &Event,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = Irp->IoStatus.Status;
+ } else {
+ ASSERT3U(status, ==, Irp->IoStatus.Status);
+ }
+
+ Trace("%08x\n", status);
+
+ return status;
+}
+
+static FORCEINLINE VOID
+__FdoAcquireMutex(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ AcquireMutex(&Fdo->Mutex);
+}
+
+VOID
+FdoAcquireMutex(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ __FdoAcquireMutex(Fdo);
+}
+
+static FORCEINLINE VOID
+__FdoReleaseMutex(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ ReleaseMutex(&Fdo->Mutex);
+}
+
+VOID
+FdoReleaseMutex(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ __FdoReleaseMutex(Fdo);
+
+ if (Fdo->References == 0)
+ FdoDestroy(Fdo);
+}
+
+
+static FORCEINLINE PANSI_STRING
+__FdoMultiSzToUpcaseAnsi(
+ IN PCHAR Buffer
+ )
+{
+ PANSI_STRING Ansi;
+ LONG Index;
+ LONG Count;
+ NTSTATUS status;
+
+ Index = 0;
+ Count = 0;
+ for (;;) {
+ if (Buffer[Index] == '\0') {
+ Count++;
+ Index++;
+
+ // Check for double NUL
+ if (Buffer[Index] == '\0')
+ break;
+ } else {
+ Buffer[Index] = (CHAR)toupper(Buffer[Index]);
+ Index++;
+ }
+ }
+
+ Ansi = (PANSI_STRING)__FdoAllocate(sizeof (ANSI_STRING) * (Count + 1));
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi == NULL)
+ goto fail1;
+
+ for (Index = 0; Index < Count; Index++) {
+ ULONG Length;
+
+ Length = (ULONG)strlen(Buffer);
+ Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+ Ansi[Index].Buffer = (PCHAR)__FdoAllocate(Ansi[Index].MaximumLength);
+
+ status = STATUS_NO_MEMORY;
+ if (Ansi[Index].Buffer == NULL)
+ goto fail2;
+
+ RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+ Ansi[Index].Length = (USHORT)Length;
+
+ Buffer += Length + 1;
+ }
+
+ return Ansi;
+
+fail2:
+ Error("fail2\n");
+
+ while (--Index >= 0)
+ __FdoFree(Ansi[Index].Buffer);
+
+ __FdoFree(Ansi);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return NULL;
+}
+
+static FORCEINLINE VOID
+__FdoFreeAnsi(
+ IN PANSI_STRING Ansi
+ )
+{
+ ULONG Index;
+
+ for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+ __FdoFree(Ansi[Index].Buffer);
+
+ __FdoFree(Ansi);
+}
+
+
+static DECLSPEC_NOINLINE VOID
+FdoParseResources(
+ IN PXENIFACE_FDO Fdo,
+ IN PCM_RESOURCE_LIST RawResourceList,
+ IN PCM_RESOURCE_LIST TranslatedResourceList
+ )
+{
+ PCM_PARTIAL_RESOURCE_LIST RawPartialList;
+ PCM_PARTIAL_RESOURCE_LIST TranslatedPartialList;
+ ULONG Index;
+
+ ASSERT3U(RawResourceList->Count, ==, 1);
+ RawPartialList = &RawResourceList->List[0].PartialResourceList;
+
+ ASSERT3U(RawPartialList->Version, ==, 1);
+ ASSERT3U(RawPartialList->Revision, ==, 1);
+
+ ASSERT3U(TranslatedResourceList->Count, ==, 1);
+ TranslatedPartialList = &TranslatedResourceList->List[0].PartialResourceList;
+
+ ASSERT3U(TranslatedPartialList->Version, ==, 1);
+ ASSERT3U(TranslatedPartialList->Revision, ==, 1);
+
+ for (Index = 0; Index < TranslatedPartialList->Count; Index++) {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR RawPartialDescriptor;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedPartialDescriptor;
+
+ RawPartialDescriptor = &RawPartialList->PartialDescriptors[Index];
+ TranslatedPartialDescriptor = &TranslatedPartialList->PartialDescriptors[Index];
+
+ switch (TranslatedPartialDescriptor->Type) {
+ case CmResourceTypeMemory:
+ Fdo->Resource[MEMORY_RESOURCE].Raw = *RawPartialDescriptor;
+ Fdo->Resource[MEMORY_RESOURCE].Translated = *TranslatedPartialDescriptor;
+ break;
+
+ case CmResourceTypeInterrupt:
+ Fdo->Resource[INTERRUPT_RESOURCE].Raw = *RawPartialDescriptor;
+ Fdo->Resource[INTERRUPT_RESOURCE].Translated = *TranslatedPartialDescriptor;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+PXENBUS_STORE_INTERFACE
+FdoGetStoreInterface(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ return Fdo->StoreInterface;
+}
+
+
+PXENBUS_SUSPEND_INTERFACE
+FdoGetSuspendInterface(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ return Fdo->SuspendInterface;
+}
+
+
+static FORCEINLINE NTSTATUS
+__FdoD3ToD0(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ POWER_STATE PowerState;
+
+ Trace("====>\n");
+
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
+
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
+
+ STORE(Acquire, Fdo->StoreInterface);
+
+ PowerState.DeviceState = PowerDeviceD0;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
+ Trace("<====\n");
+
+ return STATUS_SUCCESS;
+}
+
+static FORCEINLINE VOID
+__FdoD0ToD3(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ POWER_STATE PowerState;
+
+ Trace("====>\n");
+
+ ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
+
+ PowerState.DeviceState = PowerDeviceD3;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+
+ STORE(Release, Fdo->StoreInterface);
+
+ Trace("<====\n");
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoSuspendCallbackLate(
+ IN PVOID Argument
+ )
+{
+ PXENIFACE_FDO Fdo = (PXENIFACE_FDO) Argument;
+ NTSTATUS status;
+
+ __FdoD0ToD3(Fdo);
+
+ status = __FdoD3ToD0(Fdo);
+ ASSERT(NT_SUCCESS(status));
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoD3ToD0(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ KIRQL Irql;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+
+ status = __FdoD3ToD0(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ SUSPEND(Acquire, Fdo->SuspendInterface);
+ SHARED_INFO(Acquire, Fdo->SharedInfoInterface);
+
+ Fdo->InterfacesAcquired = TRUE;
+
+ status = SUSPEND(Register,
+ Fdo->SuspendInterface,
+ SUSPEND_CALLBACK_LATE,
+ FireSuspendEvent,
+ Fdo,
+ &Fdo->SuspendCallbackLate);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ KeLowerIrql(Irql);
+
+ return STATUS_SUCCESS;
+
+fail2:
+ Error("fail2\n");
+ SHARED_INFO(Release, Fdo->SharedInfoInterface);
+ SUSPEND(Release, Fdo->SuspendInterface);
+
+ __FdoD0ToD3(Fdo);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ KeLowerIrql(Irql);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoD0ToD3(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ KIRQL Irql;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeRaiseIrql(DISPATCH_LEVEL, &Irql);
+ Fdo->InterfacesAcquired = FALSE;
+ SUSPEND(Deregister,
+ Fdo->SuspendInterface,
+ Fdo->SuspendCallbackLate);
+ Fdo->SuspendCallbackLate = NULL;
+
+ SHARED_INFO(Release, Fdo->SharedInfoInterface);
+ SUSPEND(Release, Fdo->SuspendInterface);
+
+ __FdoD0ToD3(Fdo);
+
+ KeLowerIrql(Irql);
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoS4ToS3(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemHibernate);
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoS3ToS4(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetSystemPowerState(Fdo), ==, PowerSystemSleeping3);
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoStartDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+ FdoParseResources(Fdo,
+ StackLocation->Parameters.StartDevice.AllocatedResources,
+ StackLocation->Parameters.StartDevice.AllocatedResourcesTranslated);
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
+ FdoS4ToS3(Fdo);
+ __FdoSetSystemPowerState(Fdo, PowerSystemWorking);
+
+ status = FdoD3ToD0(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ status = IoSetDeviceInterfaceState(&Fdo->InterfaceName, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+
+ if (__FdoGetDevicePnpState(Fdo) != Stopped) {
+ status = WmiInit(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+ }
+
+ __FdoSetDevicePnpState(Fdo, Started);
+
+
+ status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+
+fail5:
+ Error("fail5\n");
+ IoSetDeviceInterfaceState(&Fdo->InterfaceName, FALSE);
+
+fail4:
+ Error("fail4\n");
+ FdoD0ToD3(Fdo);
+
+fail3:
+ Error("fail3\n");
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
+
+
+ RtlZeroMemory(&Fdo->Resource, sizeof (FDO_RESOURCE) * RESOURCE_COUNT);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoQueryStopDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ __FdoSetDevicePnpState(Fdo, StopPending);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoCancelStopDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ __FdoRestoreDevicePnpState(Fdo, StopPending);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoStopDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ FdoD0ToD3(Fdo);
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
+
+
+ RtlZeroMemory(&Fdo->Resource, sizeof (FDO_RESOURCE) * RESOURCE_COUNT);
+
+ __FdoSetDevicePnpState(Fdo, Stopped);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoQueryRemoveDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ __FdoSetDevicePnpState(Fdo, RemovePending);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoCancelRemoveDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ __FdoRestoreDevicePnpState(Fdo, RemovePending);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoSurpriseRemoval(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ __FdoSetDevicePnpState(Fdo, SurpriseRemovePending);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoSetDeviceInterfaceState(&Fdo->InterfaceName, FALSE);
+ WmiFinalise(Fdo);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoRemoveDevice(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0)
+ goto done;
+
+ FdoD0ToD3(Fdo);
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ __FdoSetSystemPowerState(Fdo, PowerSystemShutdown);
+
+ RtlZeroMemory(&Fdo->Resource, sizeof (FDO_RESOURCE) * RESOURCE_COUNT);
+
+done:
+ __FdoSetDevicePnpState(Fdo, Deleted);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoSetDeviceInterfaceState(&Fdo->InterfaceName, FALSE);
+ WmiFinalise(Fdo);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ __FdoAcquireMutex(Fdo);
+ ASSERT3U(Fdo->References, !=, 0);
+ --Fdo->References;
+ __FdoReleaseMutex(Fdo);
+
+ if (Fdo->References == 0)
+ FdoDestroy(Fdo);
+
+ return status;
+}
+
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoQueryCapabilities(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ PDEVICE_CAPABILITIES Capabilities;
+ SYSTEM_POWER_STATE SystemPowerState;
+ NTSTATUS status;
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ Capabilities = StackLocation->Parameters.DeviceCapabilities.Capabilities;
+
+ Fdo->LowerDeviceCapabilities = *Capabilities;
+
+ for (SystemPowerState = (SYSTEM_POWER_STATE)0; SystemPowerState < PowerSystemMaximum; SystemPowerState++) {
+ DEVICE_POWER_STATE DevicePowerState;
+
+ DevicePowerState = Fdo->LowerDeviceCapabilities.DeviceState[SystemPowerState];
+ Trace("%s -> %s\n",
+ PowerSystemStateName(SystemPowerState),
+ PowerDeviceStateName(DevicePowerState));
+ }
+
+ status = Irp->IoStatus.Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDeviceUsageNotification(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_USAGE_NOTIFICATION_TYPE Type;
+ BOOLEAN InPath;
+ BOOLEAN NotDisableable;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ Type = StackLocation->Parameters.UsageNotification.Type;
+ InPath = StackLocation->Parameters.UsageNotification.InPath;
+
+ if (InPath) {
+ Trace("%s: ADDING %s\n",
+ __FdoGetName(Fdo),
+ DeviceUsageTypeName(Type));
+ Fdo->Usage[Type]++;
+ } else {
+ ASSERT(Fdo->Usage[Type] != 0);
+
+ Trace("%s: REMOVING %s\n",
+ __FdoGetName(Fdo),
+ DeviceUsageTypeName(Type));
+ --Fdo->Usage[Type];
+ }
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ NotDisableable = FALSE;
+ for (Type = (DEVICE_USAGE_NOTIFICATION_TYPE)0; Type <= DeviceUsageTypeDumpFile; Type++) {
+ if (Fdo->Usage[Type] != 0) {
+ NotDisableable = TRUE;
+ break;
+ }
+ }
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ if (Fdo->NotDisableable != NotDisableable) {
+ Fdo->NotDisableable = NotDisableable;
+
+ IoInvalidateDeviceState(__FdoGetPhysicalDeviceObject(Fdo));
+ }
+
+ return status;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoQueryPnpDeviceState(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ ULONG_PTR State;
+ NTSTATUS status;
+
+ if (Irp->IoStatus.Status == STATUS_SUCCESS)
+ State = Irp->IoStatus.Information;
+ else if (Irp->IoStatus.Status == STATUS_NOT_SUPPORTED)
+ State = 0;
+ else
+ goto done;
+
+ if (Fdo->NotDisableable) {
+ Info("%s: not disableable\n", __FdoGetName(Fdo));
+ State |= PNP_DEVICE_NOT_DISABLEABLE;
+ }
+
+ Irp->IoStatus.Information = State;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+done:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchPnp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
+
+ Trace("====> (%02x:%s)\n",
+ MinorFunction,
+ PnpMinorFunctionName(MinorFunction));
+
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_START_DEVICE:
+ status = FdoStartDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_STOP_DEVICE:
+ status = FdoQueryStopDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_CANCEL_STOP_DEVICE:
+ status = FdoCancelStopDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_STOP_DEVICE:
+ status = FdoStopDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ status = FdoQueryRemoveDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_SURPRISE_REMOVAL:
+ status = FdoSurpriseRemoval(Fdo, Irp);
+ break;
+
+ case IRP_MN_REMOVE_DEVICE:
+ status = FdoRemoveDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ status = FdoCancelRemoveDevice(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_CAPABILITIES:
+ status = FdoQueryCapabilities(Fdo, Irp);
+ break;
+
+ case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+ status = FdoDeviceUsageNotification(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_PNP_DEVICE_STATE:
+ status = FdoQueryPnpDeviceState(Fdo, Irp);
+ break;
+
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
+ }
+
+ Trace("<==== (%02x:%s)(%08x)\n",
+ MinorFunction,
+ PnpMinorFunctionName(MinorFunction),
+ status);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerUp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ Trace("====>\n");
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+
+ ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto done;
+
+ Info("%s -> %s\n",
+ PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
+ PowerDeviceStateName(DeviceState));
+
+ ASSERT3U(DeviceState, ==, PowerDeviceD0);
+ status = FdoD3ToD0(Fdo);
+ ASSERT(NT_SUCCESS(status));
+
+done:
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ Trace("<==== (%08x)\n", status);
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerDown(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+
+ ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
+
+ Info("%s -> %s\n",
+ PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
+ PowerDeviceStateName(DeviceState));
+
+ ASSERT3U(DeviceState, ==, PowerDeviceD3);
+
+ if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0)
+ FdoD0ToD3(Fdo);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePower(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ POWER_ACTION PowerAction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
+
+ Trace("====> (%s:%s)\n",
+ PowerDeviceStateName(DeviceState),
+ PowerActionName(PowerAction));
+
+ ASSERT3U(PowerAction, <, PowerActionShutdown);
+
+ if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
+ __FdoSetDevicePowerUp(Fdo, Irp) :
+ __FdoSetDevicePowerDown(Fdo, Irp);
+
+done:
+ Trace("<==== (%s:%s)(%08x)\n",
+ PowerDeviceStateName(DeviceState),
+ PowerActionName(PowerAction),
+ status);
+ return status;
+}
+
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+VOID
+__FdoRequestSetDevicePower(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PKEVENT Event = (PKEVENT)Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
+
+ ASSERT(NT_SUCCESS(IoStatus->Status));
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+}
+
+static VOID
+FdoRequestSetDevicePower(
+ IN PXENIFACE_FDO Fdo,
+ IN DEVICE_POWER_STATE DeviceState
+ )
+{
+ POWER_STATE PowerState;
+ KEVENT Event;
+ NTSTATUS status;
+
+ Trace("%s\n", PowerDeviceStateName(DeviceState));
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ PowerState.DeviceState = DeviceState;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_SET_POWER,
+ PowerState,
+ __FdoRequestSetDevicePower,
+ &Event,
+ NULL);
+ ASSERT(NT_SUCCESS(status));
+
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerUp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto done;
+
+ if (SystemState < PowerSystemHibernate &&
+ __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate)
+ __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
+ FdoS4ToS3(Fdo);
+
+ Info("%s -> %s\n",
+ PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
+ PowerSystemStateName(SystemState));
+
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+ FdoRequestSetDevicePower(Fdo, DeviceState);
+
+done:
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerDown(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
+
+ DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+
+ FdoRequestSetDevicePower(Fdo, DeviceState);
+
+ Info("%s -> %s\n",
+ PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
+ PowerSystemStateName(SystemState));
+
+ if (SystemState >= PowerSystemHibernate &&
+ __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) {
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ }
+
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPower(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_ACTION PowerAction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
+
+ Trace("====> (%s:%s)\n",
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction));
+
+ ASSERT3U(PowerAction, <, PowerActionShutdown);
+
+ if (SystemState == __FdoGetSystemPowerState(Fdo)) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
+ __FdoSetSystemPowerUp(Fdo, Irp) :
+ __FdoSetSystemPowerDown(Fdo, Irp);
+
+done:
+ Trace("<==== (%s:%s)(%08x)\n",
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction),
+ status);
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQueryDevicePowerUp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+
+ ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQueryDevicePowerDown(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+
+ ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQueryDevicePower(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ POWER_ACTION PowerAction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
+
+ Trace("====> (%s:%s)\n",
+ PowerDeviceStateName(DeviceState),
+ PowerActionName(PowerAction));
+
+ ASSERT3U(PowerAction, <, PowerActionShutdown);
+
+ if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
+ __FdoQueryDevicePowerUp(Fdo, Irp) :
+ __FdoQueryDevicePowerDown(Fdo, Irp);
+
+done:
+ Trace("<==== (%s:%s)(%08x)\n",
+ PowerDeviceStateName(DeviceState),
+ PowerActionName(PowerAction),
+ status);
+ return status;
+}
+
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+VOID
+__FdoRequestQueryDevicePower(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PKEVENT Event = (PKEVENT)Context;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
+
+ ASSERT(NT_SUCCESS(IoStatus->Status));
+
+ KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+}
+
+static VOID
+FdoRequestQueryDevicePower(
+ IN PXENIFACE_FDO Fdo,
+ IN DEVICE_POWER_STATE DeviceState
+ )
+{
+ POWER_STATE PowerState;
+ KEVENT Event;
+ NTSTATUS status;
+
+ Trace("%s\n", PowerDeviceStateName(DeviceState));
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ PowerState.DeviceState = DeviceState;
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_QUERY_POWER,
+ PowerState,
+ __FdoRequestQueryDevicePower,
+ &Event,
+ NULL);
+ ASSERT(NT_SUCCESS(status));
+
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQuerySystemPowerUp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+
+ status = FdoForwardIrpSynchronously(Fdo, Irp);
+ if (!NT_SUCCESS(status))
+ goto done;
+
+ DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+
+ FdoRequestQueryDevicePower(Fdo, DeviceState);
+
+done:
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQuerySystemPowerDown(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ DEVICE_POWER_STATE DeviceState;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
+
+ DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+
+ FdoRequestQueryDevicePower(Fdo, DeviceState);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoQuerySystemPower(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_ACTION PowerAction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
+
+ Trace("====> (%s:%s)\n",
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction));
+
+ ASSERT3U(PowerAction, <, PowerActionShutdown);
+
+ if (SystemState == __FdoGetSystemPowerState(Fdo)) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
+ __FdoQuerySystemPowerUp(Fdo, Irp) :
+ __FdoQuerySystemPowerDown(Fdo, Irp);
+
+done:
+ Trace("<==== (%s:%s)(%08x)\n",
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction),
+ status);
+
+ return status;
+}
+
+static NTSTATUS
+FdoDevicePower(
+ IN PXENIFACE_THREAD Self,
+ IN PVOID Context
+ )
+{
+ PXENIFACE_FDO Fdo = (PXENIFACE_FDO)Context;
+ PKEVENT Event;
+
+ Event = ThreadGetEvent(Self);
+
+ for (;;) {
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+
+ if (Fdo->DevicePowerIrp == NULL) {
+ (VOID) KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KeClearEvent(Event);
+ }
+
+ if (ThreadIsAlerted(Self))
+ break;
+
+ Irp = Fdo->DevicePowerIrp;
+
+ if (Irp == NULL)
+ continue;
+
+ Fdo->DevicePowerIrp = NULL;
+ KeMemoryBarrier();
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
+
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ (VOID) __FdoSetDevicePower(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_POWER:
+ (VOID) __FdoQueryDevicePower(Fdo, Irp);
+ break;
+
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+FdoSystemPower(
+ IN PXENIFACE_THREAD Self,
+ IN PVOID Context
+ )
+{
+ PXENIFACE_FDO Fdo = (PXENIFACE_FDO)Context;
+ PKEVENT Event;
+
+ Event = ThreadGetEvent(Self);
+
+ for (;;) {
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+
+ if (Fdo->SystemPowerIrp == NULL) {
+ (VOID) KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ KeClearEvent(Event);
+ }
+
+ if (ThreadIsAlerted(Self))
+ break;
+
+ Irp = Fdo->SystemPowerIrp;
+
+ if (Irp == NULL)
+ continue;
+
+ Fdo->SystemPowerIrp = NULL;
+ KeMemoryBarrier();
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
+
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ (VOID) __FdoSetSystemPower(Fdo, Irp);
+ break;
+
+ case IRP_MN_QUERY_POWER:
+ (VOID) __FdoQuerySystemPower(Fdo, Irp);
+ break;
+
+ default:
+ ASSERT(FALSE);
+ break;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchPower(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+ POWER_STATE_TYPE PowerType;
+ POWER_ACTION PowerAction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
+
+ if (MinorFunction != IRP_MN_QUERY_POWER &&
+ MinorFunction != IRP_MN_SET_POWER) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ PowerType = StackLocation->Parameters.Power.Type;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
+
+ if (PowerAction >= PowerActionShutdown) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ goto done;
+ }
+
+ switch (PowerType) {
+ case DevicePowerState:
+ IoMarkIrpPending(Irp);
+
+ ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
+ Fdo->DevicePowerIrp = Irp;
+ KeMemoryBarrier();
+
+ ThreadWake(Fdo->DevicePowerThread);
+
+ status = STATUS_PENDING;
+ break;
+
+ case SystemPowerState:
+ IoMarkIrpPending(Irp);
+
+ ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
+ Fdo->SystemPowerIrp = Irp;
+ KeMemoryBarrier();
+
+ ThreadWake(Fdo->SystemPowerThread);
+
+ status = STATUS_PENDING;
+ break;
+
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
+ }
+
+done:
+ return status;
+}
+
+static DECLSPEC_NOINLINE NTSTATUS
+FdoDispatchDefault(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return status;
+}
+
+NTSTATUS
+FdoCreateFile (
+ __in PXENIFACE_FDO fdoData,
+ __inout PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+
+ XenIfaceDebugPrint(TRACE, "Create \n");
+
+ if (Deleted == fdoData->Dx->DevicePnpState)
+ {
+ Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+ return STATUS_NO_SUCH_DEVICE;
+ }
+
+
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+
+NTSTATUS
+FdoClose (
+ __in PXENIFACE_FDO fdoData,
+ __inout PIRP Irp
+ )
+
+{
+
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+ XenIfaceDebugPrint(TRACE, "Close \n");
+
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+
+NTSTATUS
+FdoReadWrite (
+ __in PXENIFACE_FDO fdoData,
+ __inout PIRP Irp
+ )
+
+{
+
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+
+ XenIfaceDebugPrint(TRACE, "ReadWrite called\n");
+
+ status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest (Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+
+
+NTSTATUS
+FdoDispatch(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (StackLocation->MajorFunction) {
+ case IRP_MJ_PNP:
+ status = FdoDispatchPnp(Fdo, Irp);
+ break;
+
+ case IRP_MJ_POWER:
+ status = FdoDispatchPower(Fdo, Irp);
+ break;
+
+ case IRP_MJ_DEVICE_CONTROL:
+ status = XenIFaceIoctl(Fdo, Irp);
+ break;
+
+ case IRP_MJ_SYSTEM_CONTROL:
+ status = XenIfaceSystemControl(Fdo, Irp);
+ break;
+
+ case IRP_MJ_READ:
+ case IRP_MJ_WRITE:
+ status = FdoReadWrite(Fdo, Irp);
+ break;
+
+ case IRP_MJ_CREATE:
+ status = FdoCreateFile(Fdo, Irp);
+ break;
+
+ case IRP_MJ_CLOSE:
+ status = FdoClose(Fdo, Irp);
+ break;
+
+ default:
+ status = FdoDispatchDefault(Fdo, Irp);
+ break;
+ }
+
+ return status;
+}
+
+
+static NTSTATUS
+FdoQueryStoreInterface(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ INTERFACE Interface;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+ RtlZeroMemory(&Interface, sizeof(INTERFACE));
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ Fdo->LowerDeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
+
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+ StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+ StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_STORE_INTERFACE;
+ StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE);
+ StackLocation->Parameters.QueryInterface.Version = STORE_INTERFACE_VERSION;
+ StackLocation->Parameters.QueryInterface.Interface = &Interface;
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Interface.Version != STORE_INTERFACE_VERSION)
+ goto fail3;
+
+ Fdo->StoreInterface = (PXENBUS_STORE_INTERFACE)Interface.Context;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+
+static NTSTATUS
+FdoQuerySuspendInterface(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ INTERFACE Interface;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+ RtlZeroMemory(&Interface, sizeof(INTERFACE));
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ Fdo->LowerDeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
+
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+ StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+ StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_SUSPEND_INTERFACE;
+ StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE);
+ StackLocation->Parameters.QueryInterface.Version = SUSPEND_INTERFACE_VERSION;
+ StackLocation->Parameters.QueryInterface.Interface = &Interface;
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Interface.Version != SUSPEND_INTERFACE_VERSION)
+ goto fail3;
+
+ Fdo->SuspendInterface = (PXENBUS_SUSPEND_INTERFACE)Interface.Context;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+static NTSTATUS
+FdoQuerySharedInfoInterface(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ INTERFACE Interface;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+ RtlZeroMemory(&Interface, sizeof(INTERFACE));
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ Fdo->LowerDeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
+
+ StackLocation = IoGetNextIrpStackLocation(Irp);
+ StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+ StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_SHARED_INFO_INTERFACE;
+ StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE);
+ StackLocation->Parameters.QueryInterface.Version = SHARED_INFO_INTERFACE_VERSION;
+ StackLocation->Parameters.QueryInterface.Interface = &Interface;
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Interface.Version != SHARED_INFO_INTERFACE_VERSION)
+ goto fail3;
+
+ Fdo->SharedInfoInterface = (PXENBUS_SHARED_INFO_INTERFACE)Interface.Context;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+NTSTATUS
+FdoCreate(
+ IN PDEVICE_OBJECT PhysicalDeviceObject
+ )
+{
+ PDEVICE_OBJECT FunctionDeviceObject;
+ PXENIFACE_DX Dx;
+ PXENIFACE_FDO Fdo;
+ WCHAR Name[MAXNAMELEN * sizeof (WCHAR)];
+ ULONG Size;
+ NTSTATUS status;
+
+#pragma prefast(suppress:28197) // Possibly leaking memory 'FunctionDeviceObject'
+ status = IoCreateDevice(DriverObject,
+ sizeof (XENIFACE_DX),
+ NULL,
+ FILE_DEVICE_UNKNOWN,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &FunctionDeviceObject);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ Dx = (PXENIFACE_DX)FunctionDeviceObject->DeviceExtension;
+ RtlZeroMemory(Dx, sizeof (XENIFACE_DX));
+
+ Dx->Type = FUNCTION_DEVICE_OBJECT;
+ Dx->DeviceObject = FunctionDeviceObject;
+ Dx->DevicePnpState = Added;
+ Dx->SystemPowerState = PowerSystemShutdown;
+ Dx->DevicePowerState = PowerDeviceD3;
+
+ FunctionDeviceObject->Flags |= DO_POWER_PAGABLE;
+ FunctionDeviceObject->Flags |= DO_BUFFERED_IO;
+
+ Fdo = (PXENIFACE_FDO)__FdoAllocate(sizeof (XENIFACE_FDO));
+
+ status = STATUS_NO_MEMORY;
+ if (Fdo == NULL)
+ goto fail2;
+
+ Fdo->Dx = Dx;
+ Fdo->PhysicalDeviceObject = PhysicalDeviceObject;
+ Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject,
+ PhysicalDeviceObject);
+
+ status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ status = IoGetDeviceProperty(PhysicalDeviceObject,
+ DevicePropertyLocationInformation,
+ sizeof (Name),
+ Name,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ status = IoRegisterDeviceInterface(PhysicalDeviceObject,
+ (LPGUID)&GUID_INTERFACE_XENIFACE,
+ NULL,
+ &Fdo->InterfaceName);
+ if (!NT_SUCCESS(status))
+ goto fail6;
+
+ status = __FdoSetName(Fdo, Name);
+ if (!NT_SUCCESS(status))
+ goto fail7;
+
+ status = FdoQueryStoreInterface(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail8;
+
+ status = FdoQuerySuspendInterface(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail9;
+
+ status = FdoQuerySharedInfoInterface(Fdo);
+ if (!NT_SUCCESS(status))
+ goto fail10;
+
+ InitializeMutex(&Fdo->Mutex);
+ InitializeListHead(&Dx->ListEntry);
+ Fdo->References = 1;
+
+ FdoInitialiseXSRegistryEntries(Fdo);
+
+ KeInitializeEvent(&Fdo->registryWriteEvent, NotificationEvent, FALSE);
+
+ status = ThreadCreate(FdoRegistryThreadHandler, Fdo, &Fdo->registryThread);
+ if (!NT_SUCCESS(status))
+ goto fail11;
+
+ Info("%p (%s)\n",
+ FunctionDeviceObject,
+ __FdoGetName(Fdo));
+
+ Dx->Fdo = Fdo;
+ FunctionDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
+
+
+fail11:
+ Error("fail11\n");
+ Fdo->SharedInfoInterface = NULL;
+
+fail10:
+ Error("fail10\n");
+ Fdo->SuspendInterface = NULL;
+
+fail9:
+ Error("fail8\n");
+
+ Fdo->StoreInterface = NULL;
+
+fail8:
+ Error("fail8\n");
+
+fail7:
+ Error("fail7\n");
+ RtlFreeUnicodeString(&Fdo->InterfaceName);
+ RtlZeroMemory(&Fdo->InterfaceName,sizeof(UNICODE_STRING));
+
+fail6:
+ Error("fail6\n");
+
+fail5:
+ Error("fail5\n");
+
+ ThreadAlert(Fdo->DevicePowerThread);
+ ThreadJoin(Fdo->DevicePowerThread);
+ Fdo->DevicePowerThread = NULL;
+
+fail4:
+ Error("fail4\n");
+
+ ThreadAlert(Fdo->SystemPowerThread);
+ ThreadJoin(Fdo->SystemPowerThread);
+ Fdo->SystemPowerThread = NULL;
+
+fail3:
+ Error("fail3\n");
+
+#pragma prefast(suppress:28183) // Fdo->LowerDeviceObject could be NULL
+ IoDetachDevice(Fdo->LowerDeviceObject);
+
+ Fdo->PhysicalDeviceObject = NULL;
+ Fdo->LowerDeviceObject = NULL;
+ Fdo->Dx = NULL;
+
+ ASSERT(IsZeroMemory(Fdo, sizeof (XENIFACE_FDO)));
+ __FdoFree(Fdo);
+
+fail2:
+ Error("fail2\n");
+
+ IoDeleteDevice(FunctionDeviceObject);
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+
+
+
+VOID
+FdoDestroy(
+ IN PXENIFACE_FDO Fdo
+ )
+{
+ PXENIFACE_DX Dx = Fdo->Dx;
+ PDEVICE_OBJECT FunctionDeviceObject = Dx->DeviceObject;
+
+ ASSERT(IsListEmpty(&Dx->ListEntry));
+ ASSERT3U(Fdo->References, ==, 0);
+ ASSERT3U(__FdoGetDevicePnpState(Fdo), ==, Deleted);
+
+ Fdo->NotDisableable = FALSE;
+
+ Info("%p (%s)\n",
+ FunctionDeviceObject,
+ __FdoGetName(Fdo));
+
+ Dx->Fdo = NULL;
+
+ RtlZeroMemory(&Fdo->Mutex, sizeof (XENIFACE_MUTEX));
+
+ Fdo->InterfacesAcquired = FALSE;
+ Fdo->SuspendInterface = NULL;
+ Fdo->StoreInterface = NULL;
+ Fdo->SharedInfoInterface = NULL;
+
+ ThreadAlert(Fdo->registryThread);
+ ThreadJoin(Fdo->registryThread);
+ Fdo->registryThread = NULL;
+
+ ThreadAlert(Fdo->DevicePowerThread);
+ ThreadJoin(Fdo->DevicePowerThread);
+ Fdo->DevicePowerThread = NULL;
+
+ ThreadAlert(Fdo->SystemPowerThread);
+ ThreadJoin(Fdo->SystemPowerThread);
+ Fdo->SystemPowerThread = NULL;
+
+ IoDetachDevice(Fdo->LowerDeviceObject);
+
+ RtlZeroMemory(&Fdo->LowerDeviceCapabilities, sizeof (DEVICE_CAPABILITIES));
+ Fdo->LowerDeviceObject = NULL;
+ Fdo->PhysicalDeviceObject = NULL;
+ Fdo->Dx = NULL;
+
+ RtlZeroMemory(&Fdo->SessionLock, sizeof(FAST_MUTEX));
+ RtlZeroMemory(&Fdo->SessionHead, sizeof(LIST_ENTRY));
+ RtlZeroMemory(&Fdo->registryWriteEvent, sizeof(KEVENT));
+
+ RtlFreeUnicodeString(&Fdo->InterfaceName);
+ RtlZeroMemory(&Fdo->InterfaceName,sizeof(UNICODE_STRING));
+
+ ASSERT(IsZeroMemory(Fdo, sizeof (XENIFACE_FDO)));
+ __FdoFree(Fdo);
+
+ IoDeleteDevice(FunctionDeviceObject);
+}
+
+
--- /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 _XENIFACE_FDO_H
+#define _XENIFACE_FDO_H
+
+#include <ntddk.h>
+#include <store_interface.h>
+#include <suspend_interface.h>
+#include <shared_info_interface.h>
+
+#include "driver.h"
+#include "types.h"
+
+#include "thread.h"
+#include "mutex.h"
+
+typedef enum _FDO_RESOURCE_TYPE {
+ MEMORY_RESOURCE = 0,
+ INTERRUPT_RESOURCE,
+ RESOURCE_COUNT
+} FDO_RESOURCE_TYPE, *PFDO_RESOURCE_TYPE;
+
+typedef struct _FDO_RESOURCE {
+ CM_PARTIAL_RESOURCE_DESCRIPTOR Raw;
+ CM_PARTIAL_RESOURCE_DESCRIPTOR Translated;
+} FDO_RESOURCE, *PFDO_RESOURCE;
+
+
+typedef struct _XENIFACE_FDO {
+ struct _XENIFACE_DX *Dx;
+ PDEVICE_OBJECT LowerDeviceObject;
+ PDEVICE_OBJECT PhysicalDeviceObject;
+ DEVICE_CAPABILITIES LowerDeviceCapabilities;
+ ULONG Usage[DeviceUsageTypeDumpFile + 1];
+ BOOLEAN NotDisableable;
+
+ PXENIFACE_THREAD SystemPowerThread;
+ PIRP SystemPowerIrp;
+ PXENIFACE_THREAD DevicePowerThread;
+ PIRP DevicePowerIrp;
+
+ XENIFACE_MUTEX Mutex;
+ ULONG References;
+
+ FDO_RESOURCE Resource[RESOURCE_COUNT];
+
+
+ PXENBUS_STORE_INTERFACE StoreInterface;
+
+ PXENBUS_SUSPEND_INTERFACE SuspendInterface;
+
+ PXENBUS_SHARED_INFO_INTERFACE SharedInfoInterface;
+
+ PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate;
+
+ BOOLEAN InterfacesAcquired;
+
+ #define MAX_SESSIONS (65536)
+
+ int WmiReady;
+
+ USHORT Sessions;
+ FAST_MUTEX SessionLock;
+ LIST_ENTRY SessionHead;
+
+ PXENIFACE_THREAD registryThread;
+ KEVENT registryWriteEvent;
+
+
+ UNICODE_STRING SuggestedInstanceName;
+
+ UNICODE_STRING InterfaceName;
+
+} XENIFACE_FDO, *PXENIFACE_FDO;
+
+
+extern PCHAR
+FdoGetName(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern NTSTATUS
+FdoCreate(
+ IN PDEVICE_OBJECT PhysicalDeviceObject
+ );
+
+extern VOID
+FdoDestroy(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern VOID
+FdoAcquireMutex(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern VOID
+FdoReleaseMutex(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern PDEVICE_OBJECT
+FdoGetPhysicalDeviceObject(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern VOID
+FdoReap(
+ IN PXENIFACE_FDO Fdo
+ );
+
+extern NTSTATUS
+FdoDelegateIrp(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ );
+
+
+extern PXENBUS_STORE_INTERFACE
+FdoGetStoreInterface(
+ IN PXENIFACE_FDO Fdo
+ );
+
+
+extern PXENBUS_SUSPEND_INTERFACE
+FdoGetSuspendInterface(
+ IN PXENIFACE_FDO Fdo
+ );
+
+
+extern NTSTATUS
+FdoDispatch(
+ IN PXENIFACE_FDO Fdo,
+ IN PIRP Irp
+ );
+
+
+
+#endif // _XENIFACE_FDO_H
*/
-#include "xeniface.h"
+#include "driver.h"
#include "ioctls.h"
#include "..\..\include\xeniface_ioctls.h"
+#include "log.h"
static FORCEINLINE BOOLEAN
__IsValidStr(
static DECLSPEC_NOINLINE NTSTATUS
IoctlRead(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PCHAR Buffer,
__in ULONG InLen,
__in ULONG OutLen,
static DECLSPEC_NOINLINE NTSTATUS
IoctlWrite(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PCHAR Buffer,
__in ULONG InLen,
__in ULONG OutLen
static DECLSPEC_NOINLINE NTSTATUS
IoctlDirectory(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PCHAR Buffer,
__in ULONG InLen,
__in ULONG OutLen,
static DECLSPEC_NOINLINE NTSTATUS
IoctlRemove(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PCHAR Buffer,
__in ULONG InLen,
__in ULONG OutLen
NTSTATUS
XenIFaceIoctl(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PIRP Irp
)
{
}
done:
+
+ Irp->IoStatus.Status = status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
return status;
}
NTSTATUS
XenIFaceIoctl(
- __in PFDO_DATA Fdo,
+ __in PXENIFACE_FDO Fdo,
__in PIRP Irp
);
--- /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 _XENIFACE_LOG_H
+#define _XENIFACE_LOG_H
+
+#include <ntddk.h>
+#include <stdarg.h>
+
+#define ERROR DPFLTR_ERROR_LEVEL
+#define WARNING DPFLTR_WARNING_LEVEL
+#define TRACE DPFLTR_TRACE_LEVEL
+#define INFO DPFLTR_INFO_LEVEL
+
+#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 XenIfaceDebugPrint(LEVEL, ...) \
+ __XenIfaceDebugPrint(__MODULE__ "|" __FUNCTION__ ": ",LEVEL, __VA_ARGS__)
+
+static __inline VOID
+__XenIfaceDebugPrint (
+ __in const CHAR *Prefix,
+ __in ULONG DebugPrintLevel,
+ __in PCCHAR DebugMessage,
+ ...
+ )
+
+{
+ va_list list;
+
+#if !DBG
+ if (DebugPrintLevel == TRACE)
+ return;
+#endif
+
+ va_start(list, DebugMessage);
+
+ if (DebugMessage)
+ {
+ vDbgPrintExWithPrefix(Prefix, DPFLTR_IHVDRIVER_ID, DebugPrintLevel, DebugMessage, list);
+
+ }
+ va_end(list);
+
+ return;
+}
+
+
+#endif // _XENIFACE_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 _XENIFACE_MUTEX_H
+#define _XENIFACE_MUTEX_H
+
+#include <ntddk.h>
+
+#include "assert.h"
+
+typedef struct _XENIFACE_MUTEX {
+ PKTHREAD Owner;
+ KEVENT Event;
+} XENIFACE_MUTEX, *PXENIFACE_MUTEX;
+
+static FORCEINLINE VOID
+InitializeMutex(
+ IN PXENIFACE_MUTEX Mutex
+ )
+{
+ RtlZeroMemory(Mutex, sizeof (XENIFACE_MUTEX));
+
+ KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
+}
+
+static FORCEINLINE VOID
+__drv_maxIRQL(PASSIVE_LEVEL)
+AcquireMutex(
+ IN PXENIFACE_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 PXENIFACE_MUTEX Mutex
+ )
+{
+ ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
+ Mutex->Owner = NULL;
+
+ KeSetEvent(&Mutex->Event, IO_NO_INCREMENT, FALSE);
+}
+
+#endif // _XENIFACE_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 _XENVIF_NAMES_H_
+#define _XENVIF_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(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
+}
+
+#endif // _XENVIF_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 "thread.h"
+#include "log.h"
+#include "assert.h"
+
+#define THREAD_POOL 'ERHT'
+
+struct _XENIFACE_THREAD {
+ XENIFACE_THREAD_FUNCTION Function;
+ PVOID Context;
+ KEVENT Event;
+ BOOLEAN Alerted;
+ LONG References;
+ PKTHREAD Thread;
+};
+
+static FORCEINLINE PVOID
+__ThreadAllocate(
+ IN ULONG Length
+ )
+{
+ return __AllocateNonPagedPoolWithTag(Length, THREAD_POOL);
+}
+
+static FORCEINLINE VOID
+__ThreadFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, THREAD_POOL);
+}
+
+static FORCEINLINE VOID
+__ThreadWake(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ KeSetEvent(&Thread->Event, IO_NO_INCREMENT, FALSE);
+}
+
+VOID
+ThreadWake(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ __ThreadWake(Thread);
+}
+
+static FORCEINLINE VOID
+__ThreadAlert(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ Thread->Alerted = TRUE;
+ __ThreadWake(Thread);
+}
+
+VOID
+ThreadAlert(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ __ThreadAlert(Thread);
+}
+
+KSTART_ROUTINE ThreadFunction;
+
+VOID
+ThreadFunction(
+ IN PVOID Argument
+ )
+{
+ PXENIFACE_THREAD Self = Argument;
+ NTSTATUS status;
+
+ status = Self->Function(Self, Self->Context);
+
+ if (InterlockedDecrement(&Self->References) == 0)
+ __ThreadFree(Self);
+
+ PsTerminateSystemThread(status);
+ // NOT REACHED
+}
+
+NTSTATUS
+ThreadCreate(
+ IN XENIFACE_THREAD_FUNCTION Function,
+ IN PVOID Context,
+ OUT PXENIFACE_THREAD *Thread
+ )
+{
+ HANDLE Handle;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ (*Thread) = __ThreadAllocate(sizeof (XENIFACE_THREAD));
+
+ Warning("Create thread %p %p\n", Function, Thread);
+
+ status = STATUS_NO_MEMORY;
+ if (*Thread == NULL)
+ goto fail1;
+
+ (*Thread)->Function = Function;
+ (*Thread)->Context = Context;
+ (*Thread)->Alerted = FALSE;
+ (*Thread)->References = 2; // One for us, one for the thread function
+
+ KeInitializeEvent(&(*Thread)->Event, NotificationEvent, FALSE);
+
+ status = PsCreateSystemThread(&Handle,
+ STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
+ NULL,
+ NULL,
+ NULL,
+ ThreadFunction,
+ *Thread);
+ if (!NT_SUCCESS(status)) {
+ --(*Thread)->References; // Fake thread function termination
+ goto fail2;
+ }
+
+ status = ObReferenceObjectByHandle(Handle,
+ SYNCHRONIZE,
+ *PsThreadType,
+ KernelMode,
+ &(*Thread)->Thread,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ ZwClose(Handle);
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+ __ThreadAlert(*Thread);
+ ZwClose(Handle);
+
+fail2:
+ Error("fail2\n");
+
+ if (InterlockedDecrement(&(*Thread)->References) == 0)
+ __ThreadFree(*Thread);
+
+ *Thread = NULL;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+PKEVENT
+ThreadGetEvent(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ return &Thread->Event;
+}
+
+BOOLEAN
+ThreadIsAlerted(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ return Thread->Alerted;
+}
+
+VOID
+ThreadJoin(
+ IN PXENIFACE_THREAD Thread
+ )
+{
+ LONG References;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3P(KeGetCurrentThread(), !=, Thread->Thread);
+
+ (VOID) KeWaitForSingleObject(Thread->Thread,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ References = InterlockedDecrement(&Thread->References);
+ ASSERT3U(References, ==, 0);
+
+ __ThreadFree(Thread);
+}
+
--- /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 _XENIFACE_THREAD_H
+#define _XENIFACE_THREAD_H
+
+#include <ntddk.h>
+
+typedef struct _XENIFACE_THREAD XENIFACE_THREAD, *PXENIFACE_THREAD;
+
+typedef NTSTATUS (*XENIFACE_THREAD_FUNCTION)(PXENIFACE_THREAD, PVOID);
+
+extern NTSTATUS
+ThreadCreate(
+ IN XENIFACE_THREAD_FUNCTION Function,
+ IN PVOID Context,
+ OUT PXENIFACE_THREAD *Thread
+ );
+
+extern PKEVENT
+ThreadGetEvent(
+ IN PXENIFACE_THREAD Self
+ );
+
+extern BOOLEAN
+ThreadIsAlerted(
+ IN PXENIFACE_THREAD Self
+ );
+
+extern VOID
+ThreadWake(
+ IN PXENIFACE_THREAD Thread
+ );
+
+extern VOID
+ThreadAlert(
+ IN PXENIFACE_THREAD Thread
+ );
+
+extern VOID
+ThreadJoin(
+ IN PXENIFACE_THREAD Thread
+ );
+
+#endif // _XENIFACE_THREAD_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 _XENIFACE_TYPES_H
+#define _XENIFACE_TYPES_H
+
+typedef enum _DEVICE_OBJECT_TYPE {
+ PHYSICAL_DEVICE_OBJECT = 'ODP',
+ FUNCTION_DEVICE_OBJECT = 'ODF'
+} DEVICE_OBJECT_TYPE, *PDEVICE_OBJECT_TYPE;
+
+typedef enum _DEVICE_PNP_STATE {
+ Invalid = 0,
+ Added, // FDO only
+ Started,
+ StopPending,
+ Stopped,
+ RemovePending,
+ SurpriseRemovePending,
+ Deleted
+} DEVICE_PNP_STATE, *PDEVICE_PNP_STATE;
+
+#endif // _XENIFACE_TYPES_H
#include <ntddk.h>
#include <initguid.h>
-#include <wdmguid.h>
#include <wmistr.h>
#include <wmilib.h>
#include <stdio.h>
#define NTSTRSAFE_LIB
#include<ntstrsafe.h>
#include "wmi.h"
-#include "xeniface.h"
+#include "driver.h"
#include "..\..\include\store_interface.h"
#include "..\..\include\suspend_interface.h"
+#include "log.h"
+#include "xeniface_ioctls.h"
__drv_raisesIRQL(APC_LEVEL)
__drv_savesIRQLGlobal(OldIrql, fdoData->SessionLock)
void LockSessions(
- FDO_DATA* fdoData)
+ XENIFACE_FDO* fdoData)
{
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
ExAcquireFastMutex(&fdoData->SessionLock);
__drv_requiresIRQL(APC_LEVEL)
__drv_restoresIRQLGlobal(OldIrql, fdoData->SessionLock)
void UnlockSessions(
- FDO_DATA* fdoData)
+ XENIFACE_FDO* fdoData)
{
ASSERT(KeGetCurrentIrql() == APC_LEVEL);
ExReleaseFastMutex(&fdoData->SessionLock);
}
size_t
-GetInstanceNameSize(FDO_DATA* FdoData, const char *string) {
+GetInstanceNameSize(XENIFACE_FDO* FdoData, const char *string) {
ANSI_STRING ansi;
RtlInitAnsiString(&ansi, string);
return sizeof(USHORT) +
NTSTATUS
-GetInstanceName(UNICODE_STRING *dest, FDO_DATA* FdoData, const char *string) {
+GetInstanceName(UNICODE_STRING *dest, XENIFACE_FDO* FdoData, const char *string) {
ANSI_STRING ansi;
UNICODE_STRING unicode;
NTSTATUS status;
}
NTSTATUS
-WriteInstanceName(FDO_DATA* FdoData, const char *string, UCHAR *location)
+WriteInstanceName(XENIFACE_FDO* FdoData, const char *string, UCHAR *location)
{
UNICODE_STRING destination;
NTSTATUS status;
typedef struct _XenStoreWatch {
LIST_ENTRY listentry;
UNICODE_STRING path;
- FDO_DATA *fdoData;
+ XENIFACE_FDO *fdoData;
ULONG suspendcount;
BOOLEAN finished;
XenStoreSession*
-FindSessionLocked(FDO_DATA *fdoData,
+FindSessionLocked(XENIFACE_FDO *fdoData,
LONG id) {
XenStoreSession *session;
}
-void FireSuspendEvent(PFDO_DATA fdoData) {
+void FireSuspendEvent(PXENIFACE_FDO fdoData) {
XenIfaceDebugPrint(ERROR,"Ready to unsuspend Event\n");
KeSetEvent(&fdoData->registryWriteEvent, IO_NO_INCREMENT, FALSE);
if (fdoData->WmiReady) {
XenIfaceDebugPrint(TRACE,"Fire Suspend Event\n");
- WmiFireEvent(fdoData->Self,
+ WmiFireEvent(fdoData->Dx->DeviceObject,
(LPGUID)&CitrixXenStoreUnsuspendedEvent_GUID,
0,
0,
if (eventdata !=NULL) {
XenIfaceDebugPrint(TRACE,"Fire Watch Event\n");
- WmiFireEvent(watch->fdoData->Self,
+ WmiFireEvent(watch->fdoData->Dx->DeviceObject,
(LPGUID)&CitrixXenStoreWatchEvent_GUID,
0,
RequiredSize,
KSTART_ROUTINE WatchCallbackThread;
NTSTATUS
-StartWatch(FDO_DATA *fdoData, XenStoreWatch *watch)
+StartWatch(XENIFACE_FDO *fdoData, XenStoreWatch *watch)
{
char *tmppath;
ANSI_STRING ansipath;
NTSTATUS
SessionAddWatchLocked(XenStoreSession *session,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *path,
XenStoreWatch **watch) {
XenStoreSession*
-FindSessionByInstanceLocked(FDO_DATA *fdoData,
+FindSessionByInstanceLocked(XENIFACE_FDO *fdoData,
UNICODE_STRING *instance) {
XenStoreSession *session;
__drv_raisesIRQL(APC_LEVEL)
__drv_savesIRQLGlobal(OldIrql, fdoData->SessionLock)
XenStoreSession *
-FindSessionByInstanceAndLock(FDO_DATA *fdoData,
+FindSessionByInstanceAndLock(XENIFACE_FDO *fdoData,
UNICODE_STRING *instance) {
XenStoreSession *session;
LockSessions(fdoData);
}
NTSTATUS
-CreateNewSession(FDO_DATA *fdoData,
+CreateNewSession(XENIFACE_FDO *fdoData,
UNICODE_STRING *stringid,
ULONG *sessionid) {
XenStoreSession *session;
}
void
-RemoveSessionLocked(FDO_DATA *fdoData,
+RemoveSessionLocked(XENIFACE_FDO *fdoData,
XenStoreSession *session) {
XenIfaceDebugPrint(TRACE,"RemoveSessionLocked\n");
}
void
-RemoveSession(FDO_DATA *fdoData,
+RemoveSession(XENIFACE_FDO *fdoData,
XenStoreSession *session) {
XenIfaceDebugPrint(TRACE,"RemoveSession\n");
LockSessions(fdoData);
UnlockSessions(fdoData);
}
-void SessionsRemoveAll(FDO_DATA *fdoData) {
-
+void SessionsRemoveAll(XENIFACE_FDO *fdoData) {
+ XenIfaceDebugPrint(TRACE,"lock");
LockSessions(fdoData);
+ XenIfaceDebugPrint(TRACE,"in lock");
while (fdoData->SessionHead.Flink != &fdoData->SessionHead) {
RemoveSessionLocked(fdoData, (XenStoreSession *)fdoData->SessionHead.Flink);
}
+ XenIfaceDebugPrint(TRACE,"unlock");
UnlockSessions(fdoData);
+ XenIfaceDebugPrint(TRACE,"unlocked");
}
ExReleaseFastMutex(&session->WatchMapLock);
}
-void SuspendSessionLocked(FDO_DATA *fdoData,
+void SuspendSessionLocked(XENIFACE_FDO *fdoData,
XenStoreSession *session) {
SessionUnwatchWatchesLocked(session);
if (session->transaction != NULL) {
}
-void SessionsSuspendAll(FDO_DATA *fdoData) {
+void SessionsSuspendAll(XENIFACE_FDO *fdoData) {
XenStoreSession *session;
LockSessions(fdoData);
XenIfaceDebugPrint(TRACE,"Suspend all sessions\n");
ExReleaseFastMutex(&session->WatchMapLock);
}
-void ResumeSessionLocked(FDO_DATA *fdoData,
+void ResumeSessionLocked(XENIFACE_FDO *fdoData,
XenStoreSession *session) {
SessionRenewWatchesLocked(session);
}
-void SessionsResumeAll(FDO_DATA *fdoData) {
+void SessionsResumeAll(XENIFACE_FDO *fdoData) {
XenStoreSession *session;
LockSessions(fdoData);
NTSTATUS
WmiInit(
- PFDO_DATA FdoData
+ PXENIFACE_FDO FdoData
)
{
NTSTATUS status = STATUS_SUCCESS;
- IoWMISuggestInstanceName(FdoData->UnderlyingPDO, NULL, FALSE,
+ IoWMISuggestInstanceName(FdoData->PhysicalDeviceObject, NULL, FALSE,
&FdoData->SuggestedInstanceName);
InitializeListHead(&FdoData->SessionHead);
FdoData->Sessions = 0;
ExInitializeFastMutex(&FdoData->SessionLock);
- status = IoWMIRegistrationControl(FdoData->Self, WMIREG_ACTION_REGISTER);
+ status = IoWMIRegistrationControl(FdoData->Dx->DeviceObject, WMIREG_ACTION_REGISTER);
FdoData->WmiReady = 1;
return status;
}
NTSTATUS
WmiFinalise(
- PFDO_DATA FdoData
+ PXENIFACE_FDO FdoData
)
{
NTSTATUS status = STATUS_SUCCESS;
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
SessionsRemoveAll(FdoData);
- status =IoWMIRegistrationControl(FdoData->Self, WMIREG_ACTION_DEREGISTER);
+ status =IoWMIRegistrationControl(FdoData->Dx->DeviceObject, WMIREG_ACTION_DEREGISTER);
+ RtlFreeUnicodeString(&FdoData->SuggestedInstanceName);
+ RtlZeroBytes(&FdoData->SuggestedInstanceName, sizeof(UNICODE_STRING));
+
FdoData->WmiReady = 0;
}
return status;
NTSTATUS
WmiChangeSingleInstance(
- PDEVICE_OBJECT DeviceObject,
+ PXENIFACE_FDO Fdo,
PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
NTSTATUS
WmiChangeSingleItem(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO Fdo,
IN PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
NTSTATUS
WmiDisableCollection(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO Fdo,
IN PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
NTSTATUS
WmiDisableEvents(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO Fdo,
IN PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
NTSTATUS
WmiEnableCollection(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO Fdo,
IN PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
NTSTATUS
WmiEnableEvents(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO Fdo,
IN PIO_STACK_LOCATION stack
)
{
- UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Fdo);
UNREFERENCED_PARAMETER(stack);
XenIfaceDebugPrint(TRACE,"%s\n",__FUNCTION__);
return STATUS_NOT_SUPPORTED;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
XenStoreSession *session;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
int i;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
UNICODE_STRING *instance,
OUT ULONG_PTR *byteswritten) {
NTSTATUS status;
ULONG InBufferSize,
UCHAR *OutBuffer,
ULONG OutBufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
UNICODE_STRING ustring;
NTSTATUS
SessionExecuteMethod(UCHAR *Buffer,
ULONG BufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
WNODE_METHOD_ITEM *Method;
NTSTATUS
BaseExecuteMethod(UCHAR *Buffer,
ULONG BufferSize,
- FDO_DATA* fdoData,
+ XENIFACE_FDO* fdoData,
OUT ULONG_PTR *byteswritten) {
ULONG RequiredSize;
WNODE_METHOD_ITEM *Method;
NTSTATUS
WmiExecuteMethod(
- IN PFDO_DATA fdoData,
+ IN PXENIFACE_FDO fdoData,
IN PIO_STACK_LOCATION stack,
OUT ULONG_PTR *byteswritten
)
NTSTATUS
GenerateSessionBlock(UCHAR *Buffer,
ULONG BufferSize,
- PFDO_DATA fdoData,
+ PXENIFACE_FDO fdoData,
ULONG_PTR *byteswritten) {
WNODE_ALL_DATA *node;
ULONG RequiredSize;
}
NTSTATUS
-GenerateBaseBlock( FDO_DATA *fdoData,
+GenerateBaseBlock( XENIFACE_FDO *fdoData,
UCHAR *Buffer,
ULONG BufferSize,
ULONG_PTR *byteswritten) {
}
NTSTATUS
GenerateBaseInstance(
- FDO_DATA *fdoData,
+ XENIFACE_FDO *fdoData,
UCHAR *Buffer,
ULONG BufferSize,
ULONG_PTR *byteswritten) {
NTSTATUS
GenerateSessionInstance(UCHAR *Buffer,
ULONG BufferSize,
- FDO_DATA *fdoData,
+ XENIFACE_FDO *fdoData,
ULONG_PTR *byteswritten) {
WNODE_SINGLE_INSTANCE *node;
ULONG RequiredSize;
NTSTATUS
WmiQueryAllData(
- IN PFDO_DATA fdoData,
+ IN PXENIFACE_FDO fdoData,
IN PIO_STACK_LOCATION stack,
OUT ULONG_PTR *byteswritten
)
NTSTATUS
WmiQuerySingleInstance(
- IN PFDO_DATA fdoData,
+ IN PXENIFACE_FDO fdoData,
IN PIO_STACK_LOCATION stack,
OUT ULONG_PTR *byteswritten
)
NTSTATUS
WmiRegInfo(
- IN PFDO_DATA fdoData,
+ IN PXENIFACE_FDO fdoData,
IN PIO_STACK_LOCATION stack,
OUT ULONG_PTR *byteswritten
)
WMI_BUFFER, sizeof(WMIREGINFO), (UCHAR **)®info,
WMI_BUFFER, entries * sizeof(WMIREGGUID), (UCHAR **)&guiddata,
WMI_STRING, mofnamesz, &mofnameptr,
- WMI_STRING, Globals.RegistryPath.Length+sizeof(USHORT),
+ WMI_STRING, DriverParameters.RegistryPath.Length+sizeof(USHORT),
®path,
WMI_DONE)){
reginfo->BufferSize = RequiredSize;
reginfo->MofResourceName = (ULONG)((ULONG_PTR)mofnameptr - (ULONG_PTR)reginfo);
WriteCountedUnicodeString(&mofname, mofnameptr);
reginfo->RegistryPath = (ULONG)((ULONG_PTR)regpath - (ULONG_PTR)reginfo);
- WriteCountedUnicodeString(&Globals.RegistryPath, regpath);
+ WriteCountedUnicodeString(&DriverParameters.RegistryPath, regpath);
}
reginfo->BufferSize = RequiredSize;
guid->InstanceCount = 1;
guid->Guid = CitrixXenStoreBase_GUID;
guid->Flags = WMIREG_FLAG_INSTANCE_PDO;
- guid->Pdo = (ULONG_PTR)fdoData->UnderlyingPDO;
- ObReferenceObject(fdoData->UnderlyingPDO);
+ guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
+ ObReferenceObject(fdoData->PhysicalDeviceObject);
guid = ®info->WmiRegGuid[1];
guid->Guid = CitrixXenStoreSession_GUID;
guid->Guid = CitrixXenStoreWatchEvent_GUID;
guid->Flags = WMIREG_FLAG_INSTANCE_PDO |
WMIREG_FLAG_EVENT_ONLY_GUID ;
- guid->Pdo = (ULONG_PTR)fdoData->UnderlyingPDO;
- ObReferenceObject(fdoData->UnderlyingPDO);
+ guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
+ ObReferenceObject(fdoData->PhysicalDeviceObject);
guid = ®info->WmiRegGuid[3];
guid->InstanceCount = 1;
guid->Guid = CitrixXenStoreUnsuspendedEvent_GUID;
guid->Flags = WMIREG_FLAG_INSTANCE_PDO |
WMIREG_FLAG_EVENT_ONLY_GUID ;
- guid->Pdo = (ULONG_PTR)fdoData->UnderlyingPDO;
- ObReferenceObject(fdoData->UnderlyingPDO);
+ guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
+ ObReferenceObject(fdoData->PhysicalDeviceObject);
*byteswritten = RequiredSize;
NTSTATUS
WmiRegInfoEx(
- IN PFDO_DATA fdoData,
+ IN PXENIFACE_FDO fdoData,
IN PIO_STACK_LOCATION stack,
OUT ULONG_PTR *byteswritten
)
NTSTATUS
WmiProcessMinorFunction(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PXENIFACE_FDO fdoData,
IN PIRP Irp
)
{
PIO_STACK_LOCATION stack;
UCHAR MinorFunction;
- PFDO_DATA fdoData;
- fdoData = (PFDO_DATA)DeviceObject->DeviceExtension;
+
stack = IoGetCurrentIrpStackLocation(Irp);
+ if (stack->Parameters.WMI.ProviderId != (ULONG_PTR)fdoData->Dx->DeviceObject) {
+ XenIfaceDebugPrint(TRACE,"ProviderID %p %p", stack->Parameters.WMI.ProviderId, fdoData->PhysicalDeviceObject);
+ return STATUS_NOT_SUPPORTED;
+ }
+ else {
+ XenIfaceDebugPrint(TRACE,"ProviderID Match %p %p", stack->Parameters.WMI.ProviderId, fdoData->PhysicalDeviceObject);
+ }
MinorFunction = stack->MinorFunction;
switch (MinorFunction)
{
case IRP_MN_CHANGE_SINGLE_INSTANCE:
- return WmiChangeSingleInstance(DeviceObject, stack);
+ return WmiChangeSingleInstance(fdoData, stack);
case IRP_MN_CHANGE_SINGLE_ITEM:
- return WmiChangeSingleItem(DeviceObject, stack);
+ return WmiChangeSingleItem(fdoData, stack);
case IRP_MN_DISABLE_COLLECTION:
- return WmiDisableCollection(DeviceObject, stack);
+ return WmiDisableCollection(fdoData, stack);
case IRP_MN_DISABLE_EVENTS:
- return WmiDisableEvents(DeviceObject, stack);
+ return WmiDisableEvents(fdoData, stack);
case IRP_MN_ENABLE_COLLECTION:
- return WmiEnableCollection(DeviceObject, stack);
+ return WmiEnableCollection(fdoData, stack);
case IRP_MN_ENABLE_EVENTS:
- return WmiEnableEvents(DeviceObject, stack);
+ return WmiEnableEvents(fdoData, stack);
case IRP_MN_EXECUTE_METHOD:
return WmiExecuteMethod(fdoData, stack, &Irp->IoStatus.Information);
case IRP_MN_QUERY_ALL_DATA:
}
}
-
NTSTATUS XenIfaceSystemControl(
- __in PDEVICE_OBJECT DeviceObject,
+ __in PXENIFACE_FDO fdoData,
__inout PIRP Irp
)
{
- PFDO_DATA fdoData;
- NTSTATUS status;
-
- fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;
-
- XenIfaceIoIncrement (fdoData);
+ NTSTATUS status;
- if (Deleted == fdoData->DevicePnPState)
- {
- Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE;
-
- IoCompleteRequest (Irp, IO_NO_INCREMENT);
-
- XenIfaceIoDecrement (fdoData);
- return status;
- }
- status = WmiProcessMinorFunction(DeviceObject, Irp);
+ status = WmiProcessMinorFunction(fdoData, Irp);
if (status != STATUS_NOT_SUPPORTED) {
- Irp->IoStatus.Status = status;
+ Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else {
IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(fdoData->NextLowerDriver, Irp);
+ status = IoCallDriver(fdoData->LowerDeviceObject, Irp);
}
- XenIfaceIoDecrement(fdoData);
return(status);
}
+
PCHAR
WMIMinorFunctionString (
__in UCHAR MinorFunction
#define _XEVTCHN_WMI_H
#include <ntddk.h>
-#include "xeniface.h"
+#include "driver.h"
#include "wmi_generated.h"
NTSTATUS
WmiProcessMinorFunction(
- IN PDEVICE_OBJECT Pdo,
+ IN PXENIFACE_FDO Fdo,
IN PIRP Irp
);
NTSTATUS
WmiInit(
- PFDO_DATA FdoData
+ PXENIFACE_FDO FdoData
);
NTSTATUS
WmiFinalise(
- PFDO_DATA FdoData
+ PXENIFACE_FDO FdoData
);
+NTSTATUS XenIfaceSystemControl(
+ __in PXENIFACE_FDO fdoData,
+ __inout PIRP Irp
+ );
+
+void FireSuspendEvent(
+ IN OUT PXENIFACE_FDO fdoData
+ );
#endif
+++ /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.
- */
-
-#if !defined(_XENIFACE_H_)
-#define _XENIFACE_H_
-
-#include <ntddk.h>
-
-#include <wmilib.h>
-
-#include <initguid.h> // required for GUID definitions
-
-#pragma warning(disable:4100 4057)
-
-#define NTSTRSAFE_LIB
-#include <ntstrsafe.h>
-
-#include "..\..\include\store_interface.h"
-#include "..\..\include\shared_info_interface.h"
-#include "..\..\include\suspend_interface.h"
-
-#define XENIFACE_POOL_TAG (ULONG) 'XIfc'
-#define XENIFACE_FDO_INSTANCE_SIGNATURE (ULONG) 'XenI'
-
-#define XENIFACE_WAIT_WAKE_ENABLE L"WaitWakeEnabled"
-
-#define XENIFACE_POWER_SAVE_ENABLE L"PowerSaveEnabled"
-
-#if !defined(InterlockedOr) && (_WIN32_WINNT==0x0500)
-#define InterlockedOr _InterlockedOr
-#endif
-
-#if !defined(EVENT_TRACING)
-#define ERROR 0
-#define WARNING 1
-#define TRACE 2
-#define INFO 3
-
-VOID
-XenIfaceDebugPrint (
- __in ULONG DebugPrintLevel,
- __in PCCHAR DebugMessage,
- ...
- );
-
-#else
-#define WPP_CONTROL_GUIDS \
- WPP_DEFINE_CONTROL_GUID(XenIface,(C56386BD,7C67,4264,B8D9,C4A53B93CBEB), \
- WPP_DEFINE_BIT(ERROR) /* bit 0 = 0x00000001 */ \
- WPP_DEFINE_BIT(WARNING) /* bit 1 = 0x00000002 */ \
- WPP_DEFINE_BIT(TRACE) /* bit 2 = 0x00000004 */ \
- WPP_DEFINE_BIT(INFO) /* bit 3 = 0x00000008 */ \
- WPP_DEFINE_BIT(DebugFlag04) /* bit 4 = 0x00000010 */ \
- WPP_DEFINE_BIT(DebugFlag05) /* bit 5 = 0x00000020 */ \
- WPP_DEFINE_BIT(DebugFlag06) /* bit 6 = 0x00000040 */ \
- WPP_DEFINE_BIT(DebugFlag07) /* bit 7 = 0x00000080 */ \
- WPP_DEFINE_BIT(DebugFlag08) /* bit 8 = 0x00000100 */ \
- WPP_DEFINE_BIT(DebugFlag09) /* bit 9 = 0x00000200 */ \
- WPP_DEFINE_BIT(DebugFlag10) /* bit 10 = 0x00000400 */ \
- WPP_DEFINE_BIT(DebugFlag11) /* bit 11 = 0x00000800 */ \
- WPP_DEFINE_BIT(DebugFlag12) /* bit 12 = 0x00001000 */ \
- WPP_DEFINE_BIT(DebugFlag13) /* bit 13 = 0x00002000 */ \
- WPP_DEFINE_BIT(DebugFlag14) /* bit 14 = 0x00004000 */ \
- WPP_DEFINE_BIT(DebugFlag15) /* bit 15 = 0x00008000 */ \
- WPP_DEFINE_BIT(DebugFlag16) /* bit 16 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag17) /* bit 17 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag18) /* bit 18 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag19) /* bit 19 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag20) /* bit 20 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag21) /* bit 21 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag22) /* bit 22 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag23) /* bit 23 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag24) /* bit 24 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag25) /* bit 25 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag26) /* bit 26 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag27) /* bit 27 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag28) /* bit 28 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag29) /* bit 29 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag30) /* bit 30 = 0x00000000 */ \
- WPP_DEFINE_BIT(DebugFlag31) /* bit 31 = 0x00000000 */ \
- )
-#endif
-
-typedef struct _GLOBALS {
-
- UNICODE_STRING RegistryPath;
-
-} GLOBALS;
-
-extern GLOBALS Globals;
-
-#define XENIFACE_WMI_STD_I8042 0
-#define XENIFACE_WMI_STD_SERIAL 1
-#define XENIFACE_WMI_STD_PARALEL 2
-#define XENIFACE_WMI_STD_USB 3
-
-typedef struct _XENIFACE_WMI_STD_DATA {
-
- UINT32 ConnectorType;
-
- UINT32 Capacity;
-
- UINT32 ErrorCount;
-
- UINT32 Controls;
-
- UINT32 DebugPrintLevel;
-
-} XENIFACE_WMI_STD_DATA, * PXENIFACE_WMI_STD_DATA;
-
-typedef enum _DEVICE_PNP_STATE {
-
- NotStarted = 0,
- Started,
- StopPending,
- Stopped,
- RemovePending,
- SurpriseRemovePending,
- Deleted
-
-} DEVICE_PNP_STATE;
-
-#define INITIALIZE_PNP_STATE(_Data_) \
- (_Data_)->DevicePnPState = NotStarted;\
- (_Data_)->PreviousPnPState = NotStarted;
-
-#define SET_NEW_PNP_STATE(_Data_, _state_) \
- (_Data_)->PreviousPnPState = (_Data_)->DevicePnPState;\
- (_Data_)->DevicePnPState = (_state_);
-
-#define RESTORE_PREVIOUS_PNP_STATE(_Data_) \
- (_Data_)->DevicePnPState = (_Data_)->PreviousPnPState;\
-
-typedef enum _QUEUE_STATE {
-
- HoldRequests = 0,
- AllowRequests,
- FailRequests
-
-} QUEUE_STATE;
-
-typedef enum {
-
- WAKESTATE_DISARMED = 1,
- WAKESTATE_WAITING = 2,
- WAKESTATE_WAITING_CANCELLED = 3,
- WAKESTATE_ARMED = 4,
- WAKESTATE_ARMING_CANCELLED = 5,
- WAKESTATE_COMPLETING = 7
-} WAKESTATE;
-
-typedef struct _FDO_DATA
-{
-
-
- ULONG Signature;
-
- PDEVICE_OBJECT Self;
-
- PDEVICE_OBJECT UnderlyingPDO;
-
- PDEVICE_OBJECT NextLowerDriver;
-
- DEVICE_PNP_STATE DevicePnPState;
-
- DEVICE_PNP_STATE PreviousPnPState;
-
- UNICODE_STRING InterfaceName;
-
-
- QUEUE_STATE QueueState;
-
- LIST_ENTRY NewRequestsQueue;
-
- KSPIN_LOCK QueueLock;
-
- KEVENT RemoveEvent;
-
- KEVENT StopEvent;
-
- ULONG OutstandingIO;
-
-
-
- BOOLEAN DontDisplayInUI;
-
- SYSTEM_POWER_STATE SystemPowerState;
-
- DEVICE_POWER_STATE DevicePowerState;
-
- WMILIB_CONTEXT WmiLibInfo;
-
- XENIFACE_WMI_STD_DATA StdDeviceData;
-
- DEVICE_CAPABILITIES DeviceCaps;
-
- PIRP PendingSIrp;
-
- BOOLEAN AllowIdleDetectionRegistration;
-
- BOOLEAN AllowWakeArming;
-
-
- WAKESTATE WakeState;
-
- PIRP WakeIrp;
-
- KEVENT WakeCompletedEvent;
-
- KEVENT WakeDisableEnableLock;
-
- UNICODE_STRING SuggestedInstanceName;
-
- USHORT Sessions;
-
- FAST_MUTEX SessionLock;
-
- LIST_ENTRY SessionHead;
-
- PXENBUS_SUSPEND_CALLBACK SuspendHandler;
-
-#define MAX_SESSIONS (65536)
-
- int WmiReady;
-
- PXENBUS_SUSPEND_INTERFACE SuspendInterface;
-
- PXENBUS_STORE_INTERFACE StoreInterface;
-
- PXENBUS_SHARED_INFO_INTERFACE SharedInfoInterface;
-
- BOOLEAN InterfacesAcquired;
-
- PKTHREAD registryThread;
- KEVENT registryWriteEvent;
- KEVENT registryThreadEndEvent;
-
-} FDO_DATA, *PFDO_DATA;
-
-#define CLRMASK(x, mask) ((x) &= ~(mask));
-#define SETMASK(x, mask) ((x) |= (mask));
-
-
-DRIVER_INITIALIZE DriverEntry;
-
-DRIVER_ADD_DEVICE XenIfaceAddDevice;
-
-__drv_dispatchType(IRP_MJ_PNP)
-DRIVER_DISPATCH XenIfaceDispatchPnp;
-
-__drv_dispatchType(IRP_MJ_POWER)
-DRIVER_DISPATCH XenIfaceDispatchPower;
-
-__drv_dispatchType(IRP_MJ_DEVICE_CONTROL)
-__drv_dispatchType(IRP_MJ_READ)
-__drv_dispatchType(IRP_MJ_WRITE)
-DRIVER_DISPATCH XenIfaceDispatchIO;
-
-__drv_dispatchType(IRP_MJ_CREATE)
-DRIVER_DISPATCH XenIfaceCreate;
-
-__drv_dispatchType(IRP_MJ_CLOSE)
-DRIVER_DISPATCH XenIfaceClose;
-
-__drv_dispatchType(IRP_MJ_CLEANUP)
-DRIVER_DISPATCH XenIfaceCleanup;
-
-__drv_dispatchType(IRP_MJ_SYSTEM_CONTROL)
-DRIVER_DISPATCH XenIfaceSystemControl;
-
-DRIVER_DISPATCH XenIfaceDispatchIoctl;
-
-DRIVER_DISPATCH XenIfaceReadWrite;
-
-DRIVER_DISPATCH XenIfaceSendIrpSynchronously;
-
-DRIVER_DISPATCH XenIfaceCanStopDevice;
-
-DRIVER_DISPATCH XenIfaceCanRemoveDevice;
-
-DRIVER_UNLOAD XenIfaceUnload;
-
-DRIVER_CANCEL XenIfaceCancelQueued;
-
-IO_COMPLETION_ROUTINE XenIfaceDispatchPnpComplete;
-
-NTSTATUS
-XenIfaceStartDevice (
- __in PFDO_DATA FdoData,
- __in PIRP Irp
- );
-
-LONG
-XenIfaceIoIncrement (
- __in PFDO_DATA FdoData
- );
-
-LONG
-XenIfaceIoDecrement (
- __in PFDO_DATA FdoData
- );
-
-NTSTATUS
-XenIfaceGetDeviceCapabilities(
- __in PDEVICE_OBJECT DeviceObject,
- __in PDEVICE_CAPABILITIES DeviceCapabilities
- );
-
-NTSTATUS
-XenIfaceSetWmiDataItem(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp,
- __in ULONG GuidIndex,
- __in ULONG InstanceIndex,
- __in ULONG DataItemId,
- __in ULONG BufferSize,
- __in_bcount(BufferSize) PUCHAR Buffer
- );
-
-NTSTATUS
-XenIfaceSetWmiDataBlock(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp,
- __in ULONG GuidIndex,
- __in ULONG InstanceIndex,
- __in ULONG BufferSize,
- __in_bcount(BufferSize) PUCHAR Buffer
- );
-
-NTSTATUS
-XenIfaceQueryWmiDataBlock(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp,
- __in ULONG GuidIndex,
- __in ULONG InstanceIndex,
- __in ULONG InstanceCount,
- __inout PULONG InstanceLengthArray,
- __in ULONG BufferAvail,
- __out_bcount(BufferAvail) PUCHAR Buffer
- );
-
-NTSTATUS
-XenIfaceQueryWmiRegInfo(
- __in PDEVICE_OBJECT DeviceObject,
- __out ULONG *RegFlags,
- __out PUNICODE_STRING InstanceName,
- __out PUNICODE_STRING *RegistryPath,
- __out PUNICODE_STRING MofResourceName,
- __out PDEVICE_OBJECT *Pdo
- );
-
-PCHAR
-WMIMinorFunctionString (
- __in UCHAR MinorFunction
-);
-
-NTSTATUS
-GetDeviceFriendlyName(
- __in PDEVICE_OBJECT Pdo,
- __inout PUNICODE_STRING DeviceName
- );
-
-NTSTATUS
-XenIfaceWmiRegistration(
- __in PFDO_DATA FdoData
-);
-
-NTSTATUS
-XenIfaceWmiDeRegistration(
- __in PFDO_DATA FdoData
-);
-
-NTSTATUS
-XenIfaceReturnResources (
- __in PDEVICE_OBJECT DeviceObject
- );
-
-NTSTATUS
-XenIfaceQueueRequest(
- __in PFDO_DATA FdoData,
- __in PIRP Irp
- );
-
-
-VOID
-XenIfaceProcessQueuedRequests(
- __in PFDO_DATA FdoData
- );
-
-NTSTATUS
-XenIfaceFunctionControl(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp,
- __in ULONG GuidIndex,
- __in WMIENABLEDISABLECONTROL Function,
- __in BOOLEAN Enable
- );
-
-NTSTATUS
-XenIfaceDispatchWaitWake(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp
- );
-
-NTSTATUS
-XenIfaceSetWaitWakeEnableState(
- __in PFDO_DATA FdoData,
- __in BOOLEAN WakeState
- );
-
-BOOLEAN
-XenIfaceGetWaitWakeEnableState(
- __in PFDO_DATA FdoData
- );
-
-VOID
-XenIfaceAdjustCapabilities(
- __in PDEVICE_CAPABILITIES DeviceCapabilities
- );
-
-BOOLEAN
-XenIfaceArmForWake(
- __in PFDO_DATA FdoData,
- __in BOOLEAN DeviceStateChange
- );
-
-VOID
-XenIfaceDisarmWake(
- __in PFDO_DATA FdoData,
- __in BOOLEAN DeviceStateChange
- );
-
-NTSTATUS
-XenIfaceWaitWakeIoCompletionRoutine(
- __in PDEVICE_OBJECT DeviceObject,
- __in PIRP Irp,
- __in PVOID Context
- );
-
-VOID
-XenIfaceWaitWakePoCompletionRoutine(
- __in PDEVICE_OBJECT DeviceObject,
- __in UCHAR MinorFunction,
- __in POWER_STATE PowerState,
- __in PVOID PowerContext,
- __in PIO_STATUS_BLOCK IoStatus
- );
-
-VOID
-XenIfacePassiveLevelReArmCallbackWorker(
- __in PDEVICE_OBJECT DeviceObject,
- __in PVOID Context
- );
-
-VOID
-XenIfacePassiveLevelClearWaitWakeEnableState(
- __in PDEVICE_OBJECT DeviceObject,
- __in PVOID Context
- );
-
-VOID
-XenIfaceQueuePassiveLevelCallback(
- __in PFDO_DATA FdoData,
- __in PIO_WORKITEM_ROUTINE CallbackFunction
- );
-
-VOID
-XenIfaceRegisterForIdleDetection(
- __in PFDO_DATA FdoData,
- __in BOOLEAN DeviceStateChange
- );
-
-VOID
-XenIfaceDeregisterIdleDetection(
- __in PFDO_DATA FdoData,
- __in BOOLEAN DeviceStateChange
- );
-
-NTSTATUS
-XenIfaceSetPowerSaveEnableState(
- __in PFDO_DATA FdoData,
- __in BOOLEAN State
- );
-
-BOOLEAN
-XenIfaceGetPowerSaveEnableState(
- __in PFDO_DATA FdoData
- );
-
-VOID
-XenIfacePowerUpDevice(
- __in PFDO_DATA FdoData
- );
-
-PCHAR
-PnPMinorFunctionString (
- __in UCHAR MinorFunction
-);
-
-NTSTATUS
-FdoQueryInterfaces(
- IN FDO_DATA* Fdo
- );
-void
-FdoReleaseInterfaces(
- IN FDO_DATA* Fdo
- )
-;
-
-void
-FdoInitialiseXSRegistryEntries(
- IN FDO_DATA* Fdo
- )
-;
-
-void
-FireSuspendEvent(
- PFDO_DATA fdoData
-);
-
-
-
-void SessionsSuspendAll(FDO_DATA *fdoData);
-
-void SessionsResumeAll(FDO_DATA *fdoData);
-#endif // _XENIFACE_H_
-
-