diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /gpio/samples/simdeviceumdf | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'gpio/samples/simdeviceumdf')
| -rw-r--r-- | gpio/samples/simdeviceumdf/GpioSampleUMDF.asl | 122 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj | 282 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj.Filters | 54 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/comsup.cpp | 344 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/comsup.h | 217 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/device.cpp | 1106 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/device.h | 365 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/dllsup.cpp | 151 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/driver.cpp | 222 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/driver.h | 151 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/exports.def | 10 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/internal.h | 96 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/queue.cpp | 529 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/queue.h | 211 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/simdeviceumdf.rc | 21 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/simdeviceumdfdriver.ctl | 1 | ||||
| -rw-r--r-- | gpio/samples/simdeviceumdf/simdeviceumdfdriver.inx | 78 |
17 files changed, 3960 insertions, 0 deletions
diff --git a/gpio/samples/simdeviceumdf/GpioSampleUMDF.asl b/gpio/samples/simdeviceumdf/GpioSampleUMDF.asl new file mode 100644 index 00000000..7e52795f --- /dev/null +++ b/gpio/samples/simdeviceumdf/GpioSampleUMDF.asl @@ -0,0 +1,122 @@ + +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + + THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY + KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR + PURPOSE. + +Module Name: + + GpioSample.asl + +Abstract: + + This sample ASL file describes a sample GPIO device and a sample peripheral + device which consumes IO and interrupt resources from the GPIO device. Please + note that: + + 1. The memory and IO descriptor under the GPIO device are simply examples of + what can be described. They are commented out to illustrate this point. Actual + values will vary according to the platform specifications (e.g. GIC and memory) + + 2. The sample ASL DSDT definition block defines only the components relevant + to demonstrate GPIO IO and interrupt resource usage. Rest of the DSDT will vary + according to platform specifications. + + 3. The PNP IDs for the GPIO and peripheral device are for demonstration purposes + only. Actual values need to reflect those chosen for the actual GPIO or + peripheral device. + +--*/ + + +DefinitionBlock ("DSDT.AML", "DSDT", 0x02, "MSFT", "SAMPLE", 0x1) { + + // + // System Bus + // + + Scope (\_SB) { + + // + // Sample GPIO device + // + + Device(GPIO) { + Name (_ADR, 0) + Name (_HID, "TEST0001") + Name (_CID, "TEST0001") + Name(_UID, 4) + + Method (_CRS, 0x0, NotSerialized) { + Name (RBUF, ResourceTemplate () { + + // + // Interrupt resource. In this example, banks 0 & 1 share the same + // interrupt to the parent controller and similarly banks 2 & 3. + // + // N.B. The definition below is chosen for an arbitrary + // test platform. It needs to be changed to reflect the hardware + // configuration of the actual platform. + // + + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, , , ) {50} + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, , , ) {50} + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, , , ) {51} + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, , , ) {51} + + // + // Memory resource. The definition below is chosen for an arbitrary + // test platform. It needs to be changed to reflect the hardware + // configuration of the actual platform. + // + + Memory32Fixed(ReadWrite, 0x00100000, 0x18) + }) + + Return (RBUF) + } + + Method (_STA, 0x0, NotSerialized) { + Return(0xf) + } + + // + // Sample peripheral device + // + + Device (TDEV) { + Name (_ADR, 0) + Name (_HID, "TEST0004") + Name (_CID, "TEST0004") + Name (_UID, 1) + + Method (_CRS, 0x0, NotSerialized) { + Name (RBUF, ResourceTemplate () { + + // + // GPIO Interrupt Resources + // + + GpioInt(Edge, ActiveHigh, Exclusive, PullUp, 0, "\\_SB.GPIO", 0, ResourceConsumer,, RawDataBuffer() {1}) {2} + + // + // GPIO IO Resources + // + + GpioIo(Exclusive, PullUp, 0, 0,, "\\_SB.GPIO",0, ResourceConsumer, , RawDataBuffer() {1}) {10} + }) + + Return (RBUF) + } + + Method (_STA, 0x0, NotSerialized) { + Return(0xf) + } + } + } + } + } diff --git a/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj b/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj new file mode 100644 index 00000000..05a8bfe6 --- /dev/null +++ b/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj @@ -0,0 +1,282 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D768CF1C-AE06-4C12-B11D-21C5D70082F7}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR> + <UMDF_VERSION_MINOR>11</UMDF_VERSION_MINOR> + <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR> + <KMDF_VERSION_MINOR>11</KMDF_VERSION_MINOR> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{DF2D116B-B9CA-4AE1-BAD4-416349DA768D}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>UMDF</DriverType> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems"> + <Inf Include="simdeviceUMDFDriver.inx"> + <Architecture>$(InfArch)</Architecture> + <SpecifyArchitecture>true</SpecifyArchitecture> + <CopyOutput>.\$(IntDir)\simdeviceUMDFDriver.inf</CopyOutput> + </Inf> + </ItemGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>SimdeviceUMDF</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>SimdeviceUMDF</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>SimdeviceUMDF</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>SimdeviceUMDF</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <WIN32_WINNT_VERSION>0x0A00</WIN32_WINNT_VERSION> + <NTDDI_VERSION>0x0A000000</NTDDI_VERSION> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\mincore.lib;$(SDK_LIB_PATH)\advapi32.lib</AdditionalDependencies> + <ModuleDefinitionFile>exports.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\..\inc;$(DDK_INC_PATH)</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp" /> + <ClCompile Include="device.cpp" /> + <ClCompile Include="dllsup.cpp" /> + <ClCompile Include="driver.cpp" /> + <ClCompile Include="queue.cpp" /> + <ResourceCompile Include="SimdeviceUMDF.rc" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj.Filters b/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj.Filters new file mode 100644 index 00000000..db8bda4d --- /dev/null +++ b/gpio/samples/simdeviceumdf/SimdeviceUMDF.vcxproj.Filters @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{7B1D3759-D374-48F4-8ADD-07752C95369D}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{A065C827-3D09-4244-997C-14744BF574C4}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{9EB984ED-A895-4F5D-97FD-C72ACA844DAD}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{3940722F-AA7D-4F6A-8A19-3CD74FCBD352}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <FilesToPackage Include=".\Debug\\simdeviceUMDFDriver.inf"> + <Filter>Driver Files</Filter> + </FilesToPackage> + <Inf Include="simdeviceUMDFDriver.inx"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <ClCompile Include="comsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="dllsup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="exports.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="SimdeviceUMDF.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/gpio/samples/simdeviceumdf/comsup.cpp b/gpio/samples/simdeviceumdf/comsup.cpp new file mode 100644 index 00000000..ccafeeaf --- /dev/null +++ b/gpio/samples/simdeviceumdf/comsup.cpp @@ -0,0 +1,344 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.cpp + +Abstract: + + This module contains implementations for the functions and methods + used for providing COM support. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" + +// +// Implementation of CUnknown methods. +// + +CUnknown::CUnknown( + VOID + ) : m_ReferenceCount(1) +/*++ + + Routine Description: + + Constructor for an instance of the CUnknown class. This simply initializes + the reference count of the object to 1. The caller is expected to + call Release() if it wants to delete the object once it has been allocated. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + // do nothing. +} + +HRESULT +STDMETHODCALLTYPE +CUnknown::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method provides the basic support for query interface on CUnknown. + If the interface requested is IUnknown it references the object and + returns an interface pointer. Otherwise it returns an error. + + Arguments: + + InterfaceId - the IID being requested + + Object - a location to store the interface pointer to return. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) + { + *Object = QueryIUnknown(); + return S_OK; + } + else + { + *Object = NULL; + return E_NOINTERFACE; + } +} + +IUnknown * +CUnknown::QueryIUnknown( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IUnknown interface. + + This allows other methods to convert a CUnknown pointer into an IUnknown + pointer without a typecast and without calling QueryInterface and dealing + with the return value. + + Arguments: + + None + + Return Value: + + A pointer to the object's IUnknown interface. + +--*/ +{ + AddRef(); + return static_cast<IUnknown *>(this); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::AddRef( + VOID + ) +/*++ + + Routine Description: + + This method adds one to the object's reference count. + + Arguments: + + None + + Return Value: + + The new reference count. The caller should only use this for debugging + as the object's actual reference count can change while the caller + examines the return value. + +--*/ +{ + return InterlockedIncrement(&m_ReferenceCount); +} + +ULONG +STDMETHODCALLTYPE +CUnknown::Release( + VOID + ) +/*++ + + Routine Description: + + This method subtracts one to the object's reference count. If the count + goes to zero, this method deletes the object. + + Arguments: + + None + + Return Value: + + The new reference count. If the caller uses this value it should only be + to check for zero (i.e. this call caused or will cause deletion) or + non-zero (i.e. some other call may have caused deletion, but this one + didn't). + +--*/ +{ + ULONG count = InterlockedDecrement(&m_ReferenceCount); + + if (count == 0) + { + delete this; + } + return count; +} + +// +// Implementation of CClassFactory methods. +// + +// +// Define storage for the factory's static lock count variable. +// + +LONG CClassFactory::s_LockCount = 0; + +IClassFactory * +CClassFactory::QueryIClassFactory( + VOID + ) +/*++ + + Routine Description: + + This helper method references the object and returns a pointer to the + object's IClassFactory interface. + + This allows other methods to convert a CClassFactory pointer into an + IClassFactory pointer without a typecast and without dealing with the + return value QueryInterface. + + Arguments: + + None + + Return Value: + + A referenced pointer to the object's IClassFactory interface. + +--*/ +{ + AddRef(); + return static_cast<IClassFactory *>(this); +} + +HRESULT +CClassFactory::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method attempts to retrieve the requested interface from the object. + + If the interface is found then the reference count on that interface (and + thus the object itself) is incremented. + + Arguments: + + InterfaceId - the interface the caller is requesting. + + Object - a location to store the interface pointer. + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + // + // This class only supports IClassFactory so check for that. + // + + if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) + { + *Object = QueryIClassFactory(); + return S_OK; + } + else + { + // + // See if the base class supports the interface. + // + + return CUnknown::QueryInterface(InterfaceId, Object); + } +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::CreateInstance( + _In_opt_ IUnknown * /* OuterObject */, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This COM method is the factory routine - it creates instances of the driver + callback class and returns the specified interface on them. + + Arguments: + + OuterObject - only used for aggregation, which our driver callback class + does not support. + + InterfaceId - the interface ID the caller would like to get from our + new object. + + Object - a location to store the referenced interface pointer to the new + object. + + Return Value: + + Status. + +--*/ +{ + HRESULT hr; + + PCSimdeviceDriver driver; + + *Object = NULL; + + hr = CSimdeviceDriver::CreateInstance(&driver); + + if (SUCCEEDED(hr)) + { + hr = driver->QueryInterface(InterfaceId, Object); + driver->Release(); + } + + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CClassFactory::LockServer( + _In_ BOOL Lock + ) +/*++ + + Routine Description: + + This COM method can be used to keep the DLL in memory. However since the + driver's DllCanUnloadNow function always returns false, this has little + effect. Still it tracks the number of lock and unlock operations. + + Arguments: + + Lock - Whether the caller wants to lock or unlock the "server" + + Return Value: + + S_OK + +--*/ +{ + if (Lock) + { + InterlockedIncrement(&s_LockCount); + } + else + { + InterlockedDecrement(&s_LockCount); + } + return S_OK; +} + + diff --git a/gpio/samples/simdeviceumdf/comsup.h b/gpio/samples/simdeviceumdf/comsup.h new file mode 100644 index 00000000..550c04e0 --- /dev/null +++ b/gpio/samples/simdeviceumdf/comsup.h @@ -0,0 +1,217 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + ComSup.h + +Abstract: + + This module contains classes and functions use for providing COM support + code. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// Forward type declarations. They are here rather than in internal.h as +// you only need them if you choose to use these support classes. +// + +typedef class CUnknown *PCUnknown; +typedef class CClassFactory *PCClassFactory; + +// +// Base class to implement IUnknown. You can choose to derive your COM +// classes from this class, or simply implement IUnknown in each of your +// classes. +// + +class CUnknown : public IUnknown +{ + +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The reference count for this object. Initialized to 1 in the + // constructor. + // + + LONG m_ReferenceCount; + +// +// Protected data members and methods. These are accessible by the subclasses +// but not by other classes. +// +protected: + + // + // The constructor and destructor are protected to ensure that only the + // subclasses of CUnknown can create and destroy instances. + // + + CUnknown( + VOID + ); + + // + // The destructor MUST be virtual. Since any instance of a CUnknown + // derived class should only be deleted from within CUnknown::Release, + // the destructor MUST be virtual or only CUnknown::~CUnknown will get + // invoked on deletion. + // + // If you see that your CMyDevice specific destructor is never being + // called, make sure you haven't deleted the virtual destructor here. + // + + virtual + ~CUnknown( + VOID + ) + { + // Do nothing + } + +// +// Public Methods. These are accessible by any class. +// +public: + + IUnknown * + QueryIUnknown( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ); + + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ); + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; + +// +// Class factory support class. Create an instance of this from your +// DllGetClassObject method and modify the implementation to create +// an instance of your driver event handler class. +// + +class CClassFactory : public CUnknown, public IClassFactory +{ +// +// Private data members and methods. These are only accessible by the methods +// of this class. +// +private: + + // + // The lock count. This is shared across all instances of IClassFactory + // and can be queried through the public IsLocked method. + // + + static LONG s_LockCount; + +// +// Public Methods. These are accessible by any class. +// +public: + + IClassFactory * + QueryIClassFactory( + VOID + ); + +// +// COM Methods. +// +public: + + // + // IUnknown methods + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + __drv_arg(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IClassFactory methods. + // + + virtual + HRESULT + STDMETHODCALLTYPE + CreateInstance( + _In_opt_ IUnknown *OuterObject, + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + virtual + HRESULT + STDMETHODCALLTYPE + LockServer( + _In_ BOOL Lock + ); +}; + diff --git a/gpio/samples/simdeviceumdf/device.cpp b/gpio/samples/simdeviceumdf/device.cpp new file mode 100644 index 00000000..0ced0bd1 --- /dev/null +++ b/gpio/samples/simdeviceumdf/device.cpp @@ -0,0 +1,1106 @@ +/*++ + +Copyright (c) 1990-2010 Microsoft Corporation + +Module Name: + + Device.cpp + +Abstract: + + This is a simple UMDF device driver that consumes GPIO pins for I/O and interrupt. + + +Environment: + + UMDF + +--*/ + +// +// Inlcude the below set of headers to get the CM_RESOURCE_ definitions +// + + +#include "internal.h" + +DEFINE_GUID (GUID_DEVINTERFACE_ECHO, + 0xcdc35b6e, 0xbe4, 0x4936, 0xbf, 0x5f, 0x55, 0x37, 0x38, 0xa, 0x7c, 0x1a); +// {CDC35B6E-0BE4-4936-BF5F-5537380A7C1A} + + +HRESULT +CSimdevice::CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit, + _Out_ PCSimdevice *Device + ) +/*++ + + Routine Description: + + This method creates and initializs an instance of the driver's + device callback object. + + Arguments: + + FxDeviceInit - the settings for the device. + + Device - a location to store the referenced pointer to the device object. + + Return Value: + + Status + +--*/ +{ + PCSimdevice device; + HRESULT hr; + + // + // Allocate a new instance of the device class. + // + + device = new CSimdevice(); + + if (NULL == device) { + return E_OUTOFMEMORY; + } + + // + // Initialize the instance. + // + + hr = device->Initialize(FxDriver, FxDeviceInit); + + if (SUCCEEDED(hr)) { + *Device = device; + } + else { + device->Release(); + } + + return hr; +} + +HRESULT +CSimdevice::Initialize( + _In_ IWDFDriver * FxDriver, + _In_ IWDFDeviceInitialize * FxDeviceInit + ) + +/*++ + + Routine Description: + + This method initializes the device callback object and creates the + partner device object. + + The method should perform any device-specific configuration that: + * could fail (these can't be done in the constructor) + * must be done before the partner object is created -or- + * can be done after the partner object is created and which aren't + influenced by any device-level parameters the parent (the driver + in this case) might set. + + Arguments: + + FxDeviceInit - the settings for this device. + + Return Value: + + status. + +--*/ +{ + IWDFDevice *fxDevice; + IWDFDeviceInitialize2 *fxDeviceInit2; + HRESULT hr; + + // + // Configure things like the locking model before we go to create our + // partner device. + // + + // + // Set no locking unless you need an automatic callbacks synchronization + // + + FxDeviceInit->SetLockingConstraint(None); + + // + // Create a new FX device object and assign the new callback object to + // handle any device level events that occur. + // + + // + // Set retrieval mode to direct I/O. This needs to be done before the call + // to CreateDevice. + // + + FxDeviceInit->QueryInterface(IID_PPV_ARGS(&fxDeviceInit2)); + + if (fxDeviceInit2 == NULL) { + hr = E_FAIL; + return hr; + } + + fxDeviceInit2->SetIoTypePreference(WdfDeviceIoBufferRetrievalDeferred, + WdfDeviceIoDirect, + WdfDeviceIoDirect); + + SAFE_RELEASE(fxDeviceInit2); + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the device). We pass that to + // CreateDevice, which takes its own reference if everything works. + // + + { + IUnknown *unknown = this->QueryIUnknown(); + + hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); + + unknown->Release(); + } + + // + // If that succeeded then set our FxDevice member variable. + // + + if (SUCCEEDED(hr)) { + m_FxDevice = fxDevice; + + // + // Drop the reference we got from CreateDevice. Since this object + // is partnered with the framework object they have the same + // lifespan - there is no need for an additional reference. + // + + fxDevice->Release(); + } + + return hr; +} + +HRESULT +CSimdevice::Configure( + VOID + ) +/*++ + + Routine Description: + + This method is called after the device callback object has been initialized + and returned to the driver. It would setup the device's queues and their + corresponding callback objects. + + Arguments: + + FxDevice - the framework device object for which we're handling events. + + Return Value: + + status + +--*/ +{ + PCSimdeviceQueue defaultQueue; + + HRESULT hr; + + hr = CSimdeviceQueue::CreateInstance(m_FxDevice, &defaultQueue); + + if (FAILED(hr)) { + return hr; + } + + hr = defaultQueue->Configure(); + + if (SUCCEEDED(hr)) { + // + // In case of success store defaultQueue in our member + // The reference is transferred to m_DefaultQueue + // + + m_Queue = defaultQueue; + } + else { + // + // In case of failure release the reference + // + + defaultQueue->Release(); + } + + if (SUCCEEDED(hr)) { + hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_ECHO, + NULL); + } + + return hr; +} + +HRESULT +CSimdevice::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + + Routine Description: + + This method is called to get a pointer to one of the object's callback + interfaces. + + Since the sample driver doesn't support any of the device events, this + method simply calls the base class's BaseQueryInterface. + + If the sample is extended to include device event interfaces then this + method must be changed to check the IID and return pointers to them as + appropriate. + + Arguments: + + InterfaceId - the interface being requested + + Object - a location to store the interface pointer if successful + + Return Value: + + S_OK or E_NOINTERFACE + +--*/ +{ + HRESULT hr; + + if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackSelfManagedIo))) { + *Object = QueryIPnpCallbackSelfManagedIo(); + hr = S_OK; + } else if (IsEqualIID(InterfaceId, __uuidof(IPnpCallbackHardware2))) { + *Object = QueryIPnpCallbackHardware2(); + hr = S_OK; + } else if (IsEqualIID(InterfaceId, __uuidof(IPnpCallback))) { + *Object = QueryIPnpCallback(); + hr = S_OK; + } else { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +HRESULT +CSimdevice::OnSelfManagedIoInit( + _In_ IWDFDevice * pWdfDevice + ) +/*++ + + Routine Description: + + This method is called to allow driver to initialize any resources + that driver might need to process I/O. + + Echo driver needs a thread to process completions. We initialize + this thread here + + Arguments: + + pWdfDevice - framework device object for which to initialze resources + + Return Value: + + S_OK in case of success + HRESULT correponding to error returned by CreateThread, in case of failure + +--*/ +{ + HRESULT hr = S_OK; + + UNREFERENCED_PARAMETER(pWdfDevice); + + + m_ThreadHandle = CreateThread( NULL, // Default Security Attrib. + 0, // Initial Stack Size, + CSimdeviceQueue::CompletionThread, // Thread Func + (LPVOID)m_Queue, // Arg to Thread Func is Queue + 0, // Creation Flags + NULL ); // Don't need the Thread Id. + + if (m_ThreadHandle == NULL) { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + + return hr; +} + +void +CSimdevice::OnSelfManagedIoCleanup( + _In_ IWDFDevice * pWdfDevice + ) +/*++ + + Routine Description: + + This method is called to allow driver to cleanup any resources + that driver allocated to process I/O. + + It is critical that, in this routine driver wait for all of the + threads which it created to exit. Otherwise those threads could + continue to execute when framework unloads the driver which + would lead to a crash. + + Echo driver created a thread to handle completions. We wait for + that thread to exit in this routine + + Arguments: + + pWdfDevice - framework device object for which to cleanup resources + + Return Value: + + None + +--*/ +{ + // + // Kill the thread and + // wait for the thread to die. + // + + UNREFERENCED_PARAMETER(pWdfDevice); + + if (m_ThreadHandle) { + + // + // Ask queue to set terminate flag which will make + // the thread exit + // + + m_Queue->SetExitThread(); + + // + // Wait for the thread to exit + // + + WaitForSingleObject(m_ThreadHandle, INFINITE); + + // + // Close the thread handle + // + + CloseHandle(m_ThreadHandle); + m_ThreadHandle = NULL; + } + + // + // Release the reference we took on the queue callback object + // to keep it alive until the thread exits + // + + SAFE_RELEASE(m_Queue); +} + + +HRESULT +CSimdevice::OnPrepareHardware( + _In_ IWDFDevice3 * pWdfDevice, + _In_ IWDFCmResourceList * pWdfResourcesRaw, + _In_ IWDFCmResourceList * pWdfResourcesTranslated + ) +/*++ + +Routine Description: + + This routine is called by WUDF to initialize hardware resources (e.g. interrupts, + IO resources) + +Arguments: + + pWdfDevice - pointer to an IWDFDevice object for the device + + pWdfResourcesRaw - Supplies a pointer to a collection of framework resource + objects. This collection identifies the raw (bus-relative) hardware + resources that have been assigned to the device. + + pWdfResourcesTranslated - Supplies a pointer to a collection of framework + resource objects. This collection identifies the translated + (system-physical) hardware resources that have been assigned to the + device. The resources appear from the CPU's point of view. + +Return Value: + + HRESULT + +--*/ +{ + + ULONG i; + HRESULT hr = S_OK; + ULONG ConnectionCount = 0; + BOOLEAN fInterruptFound = FALSE; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorTranslated; + PCM_PARTIAL_RESOURCE_DESCRIPTOR DescriptorRaw; + + // + // Parse the resource list and save the resource information. + // + + for (i=0; i < pWdfResourcesTranslated->GetCount(); i++) { + + DescriptorTranslated = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pWdfResourcesTranslated->GetDescriptor(i); + DescriptorRaw = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)pWdfResourcesRaw->GetDescriptor(i); + + if(DescriptorTranslated == NULL) { + return E_FAIL; + } + + switch (DescriptorTranslated->Type) { + + // + // One or more GPIO IO resources are expected. In this implementation of the sample + // driver, however, only the first IO resource will be used (see OnD0Entry). + // + + case CmResourceTypeConnection: + + // + // Check against expected connection type for a GPIO IO descriptor + // + + if ((DescriptorTranslated->u.Connection.Class == + CM_RESOURCE_CONNECTION_CLASS_GPIO) && + (DescriptorTranslated->u.Connection.Type == + CM_RESOURCE_CONNECTION_TYPE_GPIO_IO)) { + + if (ConnectionCount >= MAX_CONNECTIONS) { + break; + } + + // + // Store GPIO IO resource connection ID in the device extension + // + + this->GetDeviceExtension()->ConnectionId[ConnectionCount].LowPart = + DescriptorTranslated->u.Connection.IdLowPart; + + this->GetDeviceExtension()->ConnectionId[ConnectionCount].HighPart = + DescriptorTranslated->u.Connection.IdHighPart; + } + + break; + + case CmResourceTypeInterrupt: + + // + // Connect the first interrupt resource we find + // + + if (fInterruptFound == FALSE) { + hr = this->SimdeviceConnectInterrupt( + pWdfDevice, + DescriptorRaw, + DescriptorTranslated); + + if (SUCCEEDED(hr)) { + fInterruptFound = TRUE; + } + } + default: + + // + // Ignore all other descriptors + // + + break; + } + } + + return hr; + +} + +HRESULT +CSimdevice::OnReleaseHardware( + _In_ IWDFDevice3 * pWdfDevice, + _In_ IWDFCmResourceList * pWdfResourcesTranslated + ) +/*++ + + +Routine Description: + + This method is called by WUDF to uninitialize the hardware. + +Parameters: + + pWdfDevice - pointer to an IWDFDevice object for the device + + pWdfResourcesTranslated - pointer to the translated resource list + +Return Values: + status + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfDevice); + UNREFERENCED_PARAMETER(pWdfResourcesTranslated); + + return S_OK; +} + +HRESULT +CSimdevice::OnD0Entry( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ) + +/*++ + +Routine Description: + +This method is called after a new device enters the system + +Parameters: + + pWdfDevice - pointer to a device object + + previousState - previous WDF power state + +Return Values: + status + +--*/ +{ + + PDEVICE_EXTENSION DevExt; + HRESULT hr = S_OK; + BYTE Data; + NTSTATUS Status; + NTSTATUS Status1; + WCHAR ReadStringBuffer[100]; + WCHAR WriteStringBuffer[100]; + + UNREFERENCED_PARAMETER(pWdfDevice); + UNREFERENCED_PARAMETER(previousState); + + DevExt = GetDeviceExtension(); + + Status = StringCbPrintfW(&ReadStringBuffer[0], + sizeof(ReadStringBuffer), + L"\\\\.\\RESOURCE_HUB\\%0*I64x", + (size_t)(sizeof(LARGE_INTEGER) * 2), + DevExt->ConnectionId[0].QuadPart); + + Status = StringCbPrintfW(&WriteStringBuffer[0], + sizeof(WriteStringBuffer), + L"\\\\.\\RESOURCE_HUB\\%0*I64x", + (size_t)(sizeof(LARGE_INTEGER) * 2), + DevExt->ConnectionId[0].QuadPart); + + // + // Connect the first GPIO IO descriptor we find (in OnPrepareHardware) for read and write operations + // + + Data = 0xDB; + Status = STATUS_SUCCESS; + Status1 = TestReadWrite(pWdfDevice, &WriteStringBuffer[0], FALSE, &Data, sizeof(Data), NULL); + if (!NT_SUCCESS(Status1)) { + Status = Status1; + } + + Data = 0; + Status1 = TestReadWrite(pWdfDevice, &ReadStringBuffer[0], TRUE, &Data, sizeof(Data), NULL); + if (!NT_SUCCESS(Status1)) { + Status = Status1; + } + + return hr; +} + +HRESULT +CSimdevice::OnD0Exit( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE TargetState + ) + +/*++ + +Routine Description: + +This method is called when a device exit D0 + +Parameters: + + pWdfDevice pointer to a device object + + TargetState - target D-state + +Return Values: + status + +--*/ + +{ + + UNREFERENCED_PARAMETER(pWdfDevice); + UNREFERENCED_PARAMETER(TargetState); + + return S_OK; +} + +HRESULT +CSimdevice::TestReadWrite( + _In_ IWDFDevice* pWdfDevice, + _In_ PWSTR RequestString, + _In_ BOOLEAN ReadOperation, + _Inout_updates_bytes_(Size) UCHAR *Data, + _In_ ULONG Size, + _Inout_opt_ IWDFRemoteTarget *IoTargetOut + ) + +/*++ + +Routine Description: + + This is a utility routine to test read or write on a set of GPIO pins. + +Arguments: + + pWdfDevice - Supplies a pointer to the framework device object. + + RequestString - Supplies a pointer to the unicode string to be opened. + + ReadOperation - Supplies a boolean that identifies whether read (TRUE) or + write (FALSE) should be performed. + + Data - Supplies a pointer containing the buffer that should be read from + or written to. + + Size - Supplies the size of the data buffer in bytes. + + IoTargetOut - Supplies a pointer that receives the IOTARGET created by + UMDF. + +Return Value: + + HRESULT + +--*/ + +{ + + IWDFMemory *pOutputMemory = NULL; + IWDFMemory *pInputMemory = NULL; + IRequestCallbackRequestCompletion *pICallback = NULL; + IWDFIoRequest *pIoRequest = NULL; + IWDFRemoteTarget *pRemoteTarget = NULL; + UMDF_IO_TARGET_OPEN_PARAMS OpenParams; + DWORD DesiredAccess; + HRESULT hr = S_OK; + IWDFRequestCompletionParams * FxComplParams = NULL; + IWDFDriver *pWdfDriver = NULL; + + UNREFERENCED_PARAMETER(IoTargetOut); + + if (ReadOperation != FALSE) { + DesiredAccess = FILE_GENERIC_READ; + + } else { + DesiredAccess = FILE_GENERIC_WRITE; + } + + // + // QueryIUnknown references the IUnknown interface that it returns + // (which is the same as referencing the CMyRemoteTarget). We pass that + // to the various Create* calls, which take their own reference if + // everything works. + // + + IUnknown * unknown = this->QueryIUnknown(); + + + IWDFDevice2 *pWdfDevice2 = NULL; + hr = pWdfDevice->QueryInterface(IID_PPV_ARGS(&pWdfDevice2)); + + // Create the IoTarget + + if (SUCCEEDED(hr)) { + hr = pWdfDevice2->CreateRemoteTarget( + unknown, + NULL, + &pRemoteTarget); + } + + // + // Determine whether the request is a read or write + // + + OpenParams.dwCreationDisposition = OPEN_EXISTING; + OpenParams.dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED; + OpenParams.dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + + + if (SUCCEEDED(hr)) { + hr = pRemoteTarget->OpenFileByName(RequestString, + DesiredAccess, + &OpenParams); + } + + // + //Create a new IO request + // + + if (SUCCEEDED(hr)) { + hr = pWdfDevice->CreateRequest(NULL, pWdfDevice, &pIoRequest); + } + + if (SUCCEEDED(hr)) { + hr = this->QueryInterface(__uuidof(IRequestCallbackRequestCompletion), (PVOID*)&pICallback); + + // + //Set completion callback + // + + if (SUCCEEDED(hr)){ + pIoRequest->SetCompletionCallback(pICallback, NULL); + } + + pWdfDevice->GetDriver(&pWdfDriver); + + hr = pWdfDriver->CreatePreallocatedWdfMemory(Data, + Size, + NULL, // no object event callback + pIoRequest, // request object as parent + &pInputMemory); + + hr = pWdfDriver->CreatePreallocatedWdfMemory(Data, + Size, + NULL, // no object event callback + pIoRequest, // request object as parent + &pOutputMemory); + + // + //Format IO request + // + + if (ReadOperation != FALSE){ + if (SUCCEEDED(hr)) { + hr = pRemoteTarget->FormatRequestForIoctl(pIoRequest, + IOCTL_GPIO_READ_PINS, + NULL, + NULL, + NULL, + pOutputMemory, + NULL); + } + } + else { + if (SUCCEEDED(hr)) { + hr = pRemoteTarget->FormatRequestForIoctl(pIoRequest, + IOCTL_GPIO_WRITE_PINS, + NULL, + pInputMemory, + NULL, + pOutputMemory, + NULL); + } + } + + // + //Send down the request + // + if (SUCCEEDED(hr)) { + hr = pIoRequest->Send(pRemoteTarget, + WDF_REQUEST_SEND_OPTION_SYNCHRONOUS, + 0); //No timeout + } + + if (SUCCEEDED(hr)) { + + // + //Get IWDFRequestCompletionParams interface and then get completion status. + // + + pIoRequest->GetCompletionParams(&FxComplParams); + hr = FxComplParams->GetCompletionStatus(); + } + + if(FAILED(hr)) { + pIoRequest->DeleteWdfObject(); + pIoRequest = NULL; + } + } + + // + // Clean-up + // + + if (pWdfDevice2 != NULL) { + SAFE_RELEASE(pWdfDevice2); + } + + if (pWdfDriver != NULL) { + SAFE_RELEASE(pWdfDriver); + } + + if (pRemoteTarget != NULL) { + pRemoteTarget->Close(); + } + + return hr; +} + + +void +CSimdevice::OnSurpriseRemoval( + _In_ IWDFDevice* pWdfDevice + ) + +/*++ + +Routine Description: + +This method is called when a device is surprise removed + +Parameters: + + pWdfDevice pointer to a device object + +Return Values: + None + +--*/ + +{ + UNREFERENCED_PARAMETER(pWdfDevice); +} + + +HRESULT +CSimdevice::OnQueryRemove( + _In_ IWDFDevice* pWdfDevice + ) +/*++ + +Routine Description: + +This method is called when a device processes the query remove IRP + +Parameters: + + pWdfDevice pointer to a device object + +Return Values: + HRESULT + +--*/ + + +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CSimdevice::OnQueryStop( + _In_ IWDFDevice* pWdfDevice + ) +/*++ + +Routine Description: + +This method is called when a device processes the query stop IRP + +Parameters: + + pWdfDevice pointer to a device object + +Return Values: + HRESULT + +--*/ +{ + UNREFERENCED_PARAMETER(pWdfDevice); + return S_OK; +} + +HRESULT +CSimdevice::SimdeviceConnectInterrupt( + _In_ IWDFDevice* pWdfDevice, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR RawResource, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedResource + ) + +/*++ + +Routine Description: + + This is a utility routine to create an interrupt descriptor from the interrupt resource + acquired from OnPrepareHardware and connect the device ISR routine. +Arguments: + + pWdfDevice - Supplies a pointer to the framework device object. + + pWdfResourcesRaw - Supplies a pointer to a collection of framework resource + objects. This collection identifies the raw (bus-relative) hardware + resources that have been assigned to the device. + + pWdfResourcesTranslated - Supplies a pointer to a collection of framework + resource objects. This collection identifies the translated + (system-physical) hardware resources that have been assigned to the + device. The resources appear from the CPU's point of view. + +Return Value: + + None. + +--*/ + +{ + + IWDFDevice3 * pIWDFDevice3 = NULL; + IWDFInterrupt * spInterrupt = NULL; + HRESULT hr = S_OK; + + if (pWdfDevice == NULL) { + hr = E_INVALIDARG; + } + + if (SUCCEEDED(hr)) { + hr = pWdfDevice->QueryInterface(IID_PPV_ARGS(&pIWDFDevice3)); + } + + if (SUCCEEDED(hr)) { + + // + // Create interrupt + // + + WUDF_INTERRUPT_CONFIG config; + WUDF_INTERRUPT_CONFIG_INIT( + &config, + &CSimdevice::OnInterruptIsr, + &CSimdevice::OnInterruptWorkItem); + + config.InterruptRaw = RawResource; + config.InterruptTranslated = TranslatedResource; + + hr = pIWDFDevice3->CreateInterrupt(&config, &spInterrupt); + } + + // + // Associate the device context with the interrupt + // + + if (SUCCEEDED(hr)) { + hr = spInterrupt->AssignContext(NULL, (void*)this); + } + + return hr; +} + +BOOLEAN +CSimdevice::OnInterruptIsr( + _In_ IWDFInterrupt* pInterrupt, + _In_ ULONG MessageID, + _In_ ULONG Reserved + ) + +/* ++ + +Routine Description: + + This method is called when an interrupt occurs. It determines if the + driver owns the interrupt and queues a work item to defer processing + of the data. + + Arguments: + + pInterrupt - pointer to the interrupt object + MessageID - interrupt message ID + Reserved - + +Return Values: + TRUE if interrupt recognized, else FALSE. + +-- */ + +{ + + UNREFERENCED_PARAMETER(MessageID); + UNREFERENCED_PARAMETER(Reserved); + + IWDFDevice* pWdfDevice = NULL; + CSimdevice* pMyDevice = NULL; + HRESULT hr; + + hr = pInterrupt->RetrieveContext((void**)&pMyDevice); + + if (FAILED(hr)) { + pWdfDevice = pInterrupt->GetDevice(); + pWdfDevice->SetPnpState(WdfPnpStateFailed, WdfTrue); + pWdfDevice->CommitPnpState(); + } + + // + // The sample driver always returns TRUE (e.g. claiming the interrupt) + // from its ISR. In reality, the driver needs to do whatever necessary to + // quiesce the interrupt before claiming the interrupt. + // If additional work needs to be done at , schedule a work item (as we do here). + // + + pInterrupt->QueueWorkItemForIsr(); + + return TRUE; +} + +VOID +CSimdevice::OnInterruptWorkItem( + _In_ IWDFInterrupt* pInterrupt, + _In_ IWDFObject* AssociatedObject + ) + +/* ++ + +Routine Description: + + This method is called on behalf of an interrupt to defer processing. + It retrieves latest data and posts it. + +Arguments: + pInterrupt - pointer to the interrupt object + AssociatedObject - pointer to the associated object + +Return Values: + None. + +--*/ +{ + + UNREFERENCED_PARAMETER(AssociatedObject); + + IWDFDevice* pWdfDevice = NULL; + CSimdevice* pMyDevice; + HRESULT hr; + + hr = pInterrupt->RetrieveContext((void**)&pMyDevice); + + if (FAILED(hr)) { + pWdfDevice = pInterrupt->GetDevice(); + pWdfDevice->SetPnpState(WdfPnpStateFailed, WdfTrue); + pWdfDevice->CommitPnpState(); + } + + + // + // The sample driver does nothing in the work item routine. The real driver + // can add code here to accomplish all that is required to complete the serving + // of the interrupt + // + + return; +} + + diff --git a/gpio/samples/simdeviceumdf/device.h b/gpio/samples/simdeviceumdf/device.h new file mode 100644 index 00000000..e0ceb68c --- /dev/null +++ b/gpio/samples/simdeviceumdf/device.h @@ -0,0 +1,365 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Device.h + +Abstract: + + This module contains the type definitions for the UMDF Echo sample + driver's device callback class. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +#include "queue.h" + +#define MAX_CONNECTIONS (4) +#define MAX_RESOURCES (10) + + +// +// The device extension for the device object +// + +typedef struct _DEVICE_EXTENSION { + + CSimdevice* MyDevice; + + IWDFDevice* Device; + IWDFDevice3* Device3; + + IWDFCmResourceList* CmResourceList; + + LARGE_INTEGER ConnectionId[MAX_CONNECTIONS]; + +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +// +// Class for the simdevice driver. +// + +class CSimdevice : + public CUnknown, + public IPnpCallbackSelfManagedIo, + public IPnpCallbackHardware2, + public IPnpCallback +{ + +// +// Private data members. +// +private: + + IWDFDevice *m_FxDevice; + + // + // Completion Thread handle used by queue callback object + // + HANDLE m_ThreadHandle; + + // + // Our queue callback object + // Strong reference - since we pass it to the thread we create + // + CSimdeviceQueue *m_Queue; + + // + // device data + // + DEVICE_EXTENSION m_DevExtension; + +// +// Private methods. +// + +private: + + CSimdevice( + VOID + ) + { + m_FxDevice = NULL; + ZeroMemory(&m_DevExtension, sizeof(DEVICE_EXTENSION)); + } + + HRESULT + Initialize( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + IPnpCallbackSelfManagedIo * + QueryIPnpCallbackSelfManagedIo( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackSelfManagedIo *>(this); + } + + IPnpCallback * + QueryIPnpCallback( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallback *>(this); + } + + IPnpCallbackHardware2 * + QueryIPnpCallbackHardware2( + VOID + ) + { + AddRef(); + return static_cast<IPnpCallbackHardware2 *>(this); + } + + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _In_ IWDFDriver *FxDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit, + _Out_ PCSimdevice *Device + ); + + HRESULT + Configure( + VOID + ); + +// +// COM methods +// +public: + + // + // IUnknown methods. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + __drv_arg(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // IPnpCallbackSelfManagedIo methods + // + + // + // We implement this interface to create and tear down + // our completion thread + // + // It is critical that we wait for all the threads we create + // to exit during OnSelfManagedIoCleanup, otherwise thread + // may continue to execute when framework unloads the driver, + // leading to a crash + // + // We don't manage any I/O separate from the queue, so apart + // from OnSelfManagedIoInit and OnSelfManagedIoCleanup, other + // methods have token implementations + // + + virtual + void + STDMETHODCALLTYPE + OnSelfManagedIoCleanup( + _In_ IWDFDevice * pWdfDevice + ); + + virtual + void + STDMETHODCALLTYPE + OnSelfManagedIoFlush( + _In_ IWDFDevice * pWdfDevice + ) + { + UNREFERENCED_PARAMETER( pWdfDevice ); + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoInit( + _In_ IWDFDevice * pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoSuspend( + _In_ IWDFDevice * pWdfDevice + ) + { + UNREFERENCED_PARAMETER( pWdfDevice ); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoRestart( + _In_ IWDFDevice * pWdfDevice + ) + { + UNREFERENCED_PARAMETER( pWdfDevice ); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnSelfManagedIoStop( + _In_ IWDFDevice * pWdfDevice + ) + { + UNREFERENCED_PARAMETER( pWdfDevice ); + + return S_OK; + } + + // + // IPnpCallback + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnD0Entry( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnD0Exit( + _In_ IWDFDevice* pWdfDevice, + _In_ WDF_POWER_DEVICE_STATE previousState + ); + + virtual + void + STDMETHODCALLTYPE + OnSurpriseRemoval( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnQueryRemove( + _In_ IWDFDevice* pWdfDevice + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnQueryStop( + _In_ IWDFDevice* pWdfDevice + ); + + // + // IPnpCallbackHardware2 + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnPrepareHardware( + _In_ IWDFDevice3 * pWdfDevice, + _In_ IWDFCmResourceList * pWdfResourcesRaw, + _In_ IWDFCmResourceList * pWdfResourcesTranslated + ); + + virtual + HRESULT + STDMETHODCALLTYPE + OnReleaseHardware( + _In_ IWDFDevice3 * pWdfDevice, + _In_ IWDFCmResourceList * pWdfResourcesTranslated + ); + + HRESULT + SimdeviceConnectInterrupt( + _In_ IWDFDevice* pWdfDevice, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR RawResource, + _In_opt_ PCM_PARTIAL_RESOURCE_DESCRIPTOR TranslatedResource + ); + + static WUDF_INTERRUPT_ISR OnInterruptIsr; + static WUDF_INTERRUPT_WORKITEM OnInterruptWorkItem; + + IWDFDevice * + GetFxDevice( + VOID + ) + { + return m_FxDevice; + } + + PDEVICE_EXTENSION + GetDeviceExtension( + VOID + ) + { + return &m_DevExtension; + } + + HRESULT + TestReadWrite( + _In_ IWDFDevice* pWdfDevice, + _In_ PWSTR RequestString, + _In_ BOOLEAN ReadOperation, + _Inout_updates_bytes_(Size) UCHAR *Data, + _In_ ULONG Size, + _Inout_opt_ IWDFRemoteTarget *IoTargetOut + ); + +}; + diff --git a/gpio/samples/simdeviceumdf/dllsup.cpp b/gpio/samples/simdeviceumdf/dllsup.cpp new file mode 100644 index 00000000..7b0ea74d --- /dev/null +++ b/gpio/samples/simdeviceumdf/dllsup.cpp @@ -0,0 +1,151 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + dllsup.cpp + +Abstract: + + This module contains the implementation of the sample UMDF Driver's + entry point and its exported functions for providing COM support. + + This module can be copied without modification to a new UMDF driver. It + depends on some of the code in comsup.cpp & comsup.h to handle DLL + registration and creating the first class factory. + + This module is dependent on the following defines: + + MYDRIVER_CLASS_ID - A GUID encoded in struct format used to + initialize the driver's ClassID. + + These are defined in internal.h for the sample. If you choose + to use a different primary include file, you should ensure they are + defined there as well. + + +Environment: + + WDF User-Mode Driver Framework (WDF:UMDF) + +--*/ + +#include "internal.h" + +const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; + +BOOL +WINAPI +DllMain( + HINSTANCE ModuleHandle, + DWORD Reason, + PVOID /* Reserved */ + ) +/*++ + + Routine Description: + + This is the entry point and exit point for the I/O trace driver. This + does very little as the I/O trace driver has minimal global data. + + This method initializes tracing. + + Arguments: + + ModuleHandle - the DLL handle for this module. + + Reason - the reason this entry point was called. + + Reserved - unused + + Return Value: + + TRUE + +--*/ +{ + + UNREFERENCED_PARAMETER(ModuleHandle); + UNREFERENCED_PARAMETER(Reason); + + return TRUE; +} + +_Check_return_ +STDAPI +DllGetClassObject( + _In_ REFCLSID ClassId, + _In_ REFIID InterfaceId, + _Outptr_ LPVOID *Interface + ) +/*++ + + Routine Description: + + This routine is called by COM in order to instantiate the + driver callback object and do an initial query interface on it. + + This method only creates an instance of the driver's class factory, as this + is the minimum required to support UMDF. + + Arguments: + + ClassId - the CLSID of the object being "gotten" + + InterfaceId - the interface the caller wants from that object. + + Interface - a location to store the referenced interface pointer + + Return Value: + + S_OK if the function succeeds or error indicating the cause of the + failure. + +--*/ +{ + PCClassFactory factory; + + HRESULT hr = S_OK; + + *Interface = NULL; + + // + // If the CLSID doesn't match that of our "coclass" (defined in the IDL + // file) then we can't create the object the caller wants. This may + // indicate that the COM registration is incorrect, and another CLSID + // is referencing this drvier. + // + + if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) + { + return CLASS_E_CLASSNOTAVAILABLE; + } + + // + // Create an instance of the class factory for the caller. + // + + factory = new CClassFactory(); + + if (NULL == factory) + { + hr = E_OUTOFMEMORY; + } + + // + // Query the object we created for the interface the caller wants. After + // that we release the object. This will drive the reference count to + // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). + // In the later case the object is automatically deleted. + // + + if (SUCCEEDED(hr)) + { + hr = factory->QueryInterface(InterfaceId, Interface); + factory->Release(); + } + + return hr; +} + diff --git a/gpio/samples/simdeviceumdf/driver.cpp b/gpio/samples/simdeviceumdf/driver.cpp new file mode 100644 index 00000000..09f47062 --- /dev/null +++ b/gpio/samples/simdeviceumdf/driver.cpp @@ -0,0 +1,222 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved. + +Module Name: + + Driver.cpp + +Abstract: + + This module contains the implementation of the UMDF Sample's + core driver callback object. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#include "internal.h" +//#include "driver.tmh" + +HRESULT +CSimdeviceDriver::CreateInstance( + _Out_ PCSimdeviceDriver *Driver + ) +/*++ + + Routine Description: + + This static method is invoked in order to create and initialize a new + instance of the driver class. The caller should arrange for the object + to be released when it is no longer in use. + + Arguments: + + Driver - a location to store a referenced pointer to the new instance + + Return Value: + + S_OK if successful, or error otherwise. + +--*/ +{ + PCSimdeviceDriver driver; + HRESULT hr; + + // + // Allocate the callback object. + // + + driver = new CSimdeviceDriver(); + + if (NULL == driver) + { + return E_OUTOFMEMORY; + } + + // + // Initialize the callback object. + // + + hr = driver->Initialize(); + + if (SUCCEEDED(hr)) + { + // + // Store a pointer to the new, initialized object in the output + // parameter. + // + + *Driver = driver; + } + else + { + + // + // Release the reference on the driver object to get it to delete + // itself. + // + + driver->Release(); + } + + return hr; +} + +HRESULT +CSimdeviceDriver::Initialize( + VOID + ) +/*++ + + Routine Description: + + This method is called to initialize a newly created driver callback object + before it is returned to the creator. Unlike the constructor, the + Initialize method contains operations which could potentially fail. + + Arguments: + + None + + Return Value: + + None + +--*/ +{ + return S_OK; +} + +HRESULT +CSimdeviceDriver::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Interface + ) +/*++ + + Routine Description: + + This method returns a pointer to the requested interface on the callback + object.. + + Arguments: + + InterfaceId - the IID of the interface to query/reference + + Interface - a location to store the interface pointer. + + Return Value: + + S_OK if the interface is supported. + E_NOINTERFACE if it is not supported. + +--*/ +{ + if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) + { + *Interface = QueryIDriverEntry(); + return S_OK; + } + else + { + return CUnknown::QueryInterface(InterfaceId, Interface); + } +} + +HRESULT +CSimdeviceDriver::OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ) +/*++ + + Routine Description: + + The FX invokes this method when it wants to install our driver on a device + stack. This method creates a device callback object, then calls the Fx + to create an Fx device object and associate the new callback object with + it. + + Arguments: + + FxWdfDriver - the Fx driver object. + + FxDeviceInit - the initialization information for the device. + + Return Value: + + status + +--*/ +{ + HRESULT hr; + + PCSimdevice device = NULL; + + // + // TODO: Do any per-device initialization (reading settings from the + // registry for example) that's necessary before creating your + // device callback object here. Otherwise you can leave such + // initialization to the initialization of the device event + // handler. + // + + // + // Create a new instance of our device callback object + // + + hr = CSimdevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); + + // + // TODO: Change any per-device settings that the object exposes before + // calling Configure to let it complete its initialization. + // + + // + // If that succeeded then call the device's construct method. This + // allows the device to create any queues or other structures that it + // needs now that the corresponding fx device object has been created. + // + + if (SUCCEEDED(hr)) + { + hr = device->Configure(); + } + + // + // Release the reference on the device callback object now that it's been + // associated with an fx device object. + // + + if (NULL != device) + { + device->Release(); + } + + return hr; +} + diff --git a/gpio/samples/simdeviceumdf/driver.h b/gpio/samples/simdeviceumdf/driver.h new file mode 100644 index 00000000..a8f464be --- /dev/null +++ b/gpio/samples/simdeviceumdf/driver.h @@ -0,0 +1,151 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Driver.h + +Abstract: + + This module contains the type definitions for the UMDF sample's + driver callback class. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// +// This class handles driver events for the sample. In particular +// it supports the OnDeviceAdd event, which occurs when the driver is called +// to setup per-device handlers for a new device stack. +// + +class CSimdeviceDriver : public CUnknown, public IDriverEntry +{ +// +// Private data members. +// +private: + +// +// Private methods. +// +private: + + // + // Returns a refernced pointer to the IDriverEntry interface. + // + + IDriverEntry * + QueryIDriverEntry( + VOID + ) + { + AddRef(); + return static_cast<IDriverEntry*>(this); + } + + HRESULT + Initialize( + VOID + ); + +// +// Public methods +// +public: + + // + // The factory method used to create an instance of this driver. + // + + static + HRESULT + CreateInstance( + _Out_ PCSimdeviceDriver *Driver + ); + +// +// COM methods +// +public: + + // + // IDriverEntry methods + // + + virtual + HRESULT + STDMETHODCALLTYPE + OnInitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER( FxWdfDriver ); + + return S_OK; + } + + virtual + HRESULT + STDMETHODCALLTYPE + OnDeviceAdd( + _In_ IWDFDriver *FxWdfDriver, + _In_ IWDFDeviceInitialize *FxDeviceInit + ); + + virtual + VOID + STDMETHODCALLTYPE + OnDeinitialize( + _In_ IWDFDriver *FxWdfDriver + ) + { + UNREFERENCED_PARAMETER( FxWdfDriver ); + + return; + } + + // + // IUnknown methods. + // + // We have to implement basic ones here that redirect to the + // base class becuase of the multiple inheritance. + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) + { + return __super::AddRef(); + } + + __drv_arg(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) + { + return __super::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); +}; + diff --git a/gpio/samples/simdeviceumdf/exports.def b/gpio/samples/simdeviceumdf/exports.def new file mode 100644 index 00000000..45a4fb2b --- /dev/null +++ b/gpio/samples/simdeviceumdf/exports.def @@ -0,0 +1,10 @@ +; Echo.def : Declares the module parameters. + +; +; TODO: Change the library name here to match your binary name. +; + +LIBRARY "SimdeviceUMDF.DLL" + +EXPORTS + DllGetClassObject PRIVATE diff --git a/gpio/samples/simdeviceumdf/internal.h b/gpio/samples/simdeviceumdf/internal.h new file mode 100644 index 00000000..4cc79b71 --- /dev/null +++ b/gpio/samples/simdeviceumdf/internal.h @@ -0,0 +1,96 @@ +/*++ + +Copyright (C) Microsoft Corporation, All Rights Reserved + +Module Name: + + Internal.h + +Abstract: + + This module contains the local type definitions for the UMDF Echo + driver sample. + + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ +#ifndef _INTERNAL_H_ +#define _INTERNAL_H_ + +#pragma once + +#define UMDF_USING_NTSTATUS + +#include <windows.h> +#include <winternl.h> +#include <ntstatus.h> +#include <strsafe.h> +#include <gpio.h> + +_Analysis_mode_(_Analysis_code_type_user_driver_); // Macro letting the compiler know this is not a kernel driver (this will help surpress needless warnings) + +// Common WPD, UMDF, and WDM headers +#include <devioctl.h> +#include <initguid.h> + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + +// +// Include the WUDF DDI +// +#include "wudfddi.h" + +// +// Use specstrings for in/out annotation of function parameters. +// + +#include "specstrings.h" + +// +// Forward definitions of classes in the other header files. +// + +typedef class CSimdeviceDriver *PCSimdeviceDriver; +typedef class CSimdevice *PCSimdevice; +typedef class CSimdeviceQueue *PCSimdeviceQueue; + +// +// Include the type specific headers. +// + +#include "comsup.h" +#include "driver.h" +#include "device.h" +#include "queue.h" + +__forceinline +#ifdef _PREFAST_ +__declspec(noreturn) +#endif +VOID +WdfTestNoReturn( + VOID + ) +{ + // do nothing. +} + +#define WUDF_TEST_DRIVER_ASSERT(p) \ +{ \ + if ( !(p) ) \ + { \ + DebugBreak(); \ + WdfTestNoReturn(); \ + } \ +} + +#define MYDRIVER_CLASS_ID {0x7ab7dcf5, 0xd1d4, 0x4085, {0x95, 0x47, 0x1d, 0xb9, 0x68, 0xcc, 0xa7, 0x20}} + + +#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} +#endif diff --git a/gpio/samples/simdeviceumdf/queue.cpp b/gpio/samples/simdeviceumdf/queue.cpp new file mode 100644 index 00000000..4b66a25f --- /dev/null +++ b/gpio/samples/simdeviceumdf/queue.cpp @@ -0,0 +1,529 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.cpp + +Abstract: + + This file implements the I/O queue interface and performs + the read/write/ioctl operations. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + + +#include "internal.h" + +// +// IUnknown implementation +// + +// +// Queue destructor. +// Free up the buffer, wait for thread to terminate and +// delete critical section. +// + + +CSimdeviceQueue::~CSimdeviceQueue( + VOID + ) +/*++ + +Routine Description: + + + IUnknown implementation of Release + +Arguments: + + +Return Value: + + ULONG (reference count after Release) + +--*/ +{ + if (m_Buffer) { + delete [] m_Buffer; + } + + if (m_InitCritSec) { + ::DeleteCriticalSection(&m_Crit); + } +} + + +// +// Initialize +HRESULT +CSimdeviceQueue::CreateInstance( + _In_ IWDFDevice *FxDevice, + _Out_ PCSimdeviceQueue *Queue + ) +/*++ + +Routine Description: + + + CreateInstance creates an instance of the queue object. + +Arguments: + + ppUkwn - OUT parameter is an IUnknown interface to the queue object + +Return Value: + + HRESULT indicating success or failure + +--*/ +{ + CSimdeviceQueue *pMyQueue = new CSimdeviceQueue; + HRESULT hr; + + if (pMyQueue == NULL) { + return E_OUTOFMEMORY; + } + + hr = pMyQueue->Initialize(FxDevice); + + if (SUCCEEDED(hr)) + { + *Queue = pMyQueue; + } + else + { + pMyQueue->Release(); + } + return hr; +} + +HRESULT +CSimdeviceQueue::Initialize( + _In_ IWDFDevice *FxDevice + ) +{ + IWDFIoQueue *fxQueue; + HRESULT hr; + + // + // Initialize the critical section before we continue + // + + if (!InitializeCriticalSectionAndSpinCount(&m_Crit,0x80000400)) { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto Exit; + } + m_InitCritSec = TRUE; + + // + // Create the framework queue + // + + { + IUnknown *unknown = QueryIUnknown(); + hr = FxDevice->CreateIoQueue(unknown, + TRUE, + WdfIoQueueDispatchSequential, + TRUE, + FALSE, + &fxQueue); + unknown->Release(); + } + + if (FAILED(hr)) { + goto Exit; + } + + m_FxQueue = fxQueue; + + fxQueue->Release(); + +Exit: + return hr; +} + +HRESULT +STDMETHODCALLTYPE +CSimdeviceQueue::QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ) +/*++ + +Routine Description: + + + Query Interface + +Arguments: + + Follows COM specifications + +Return Value: + + HRESULT indicating success or failure + +--*/ +{ + HRESULT hr; + + + if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) { + *Object = QueryIQueueCallbackWrite(); + hr = S_OK; + } else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackRead))) { + *Object = QueryIQueueCallbackRead(); + hr = S_OK; + } else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDeviceIoControl))) { + *Object = QueryIQueueCallbackDeviceIoControl(); + hr = S_OK; + } else { + hr = CUnknown::QueryInterface(InterfaceId, Object); + } + + return hr; +} + +VOID +STDMETHODCALLTYPE +CSimdeviceQueue::OnDeviceIoControl( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ) +/*++ + +Routine Description: + + + DeviceIoControl dispatch routine + +Arguments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + ControlCode - IO Control Code + InputBufferSizeInBytes - Length of input buffer + OutputBufferSizeInBytes - Length of output buffer + + Always succeeds DeviceIoIoctl +Return Value: + + VOID + +--*/ +{ + + UNREFERENCED_PARAMETER(pWdfQueue); + UNREFERENCED_PARAMETER(ControlCode); + UNREFERENCED_PARAMETER(InputBufferSizeInBytes); + UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); + + pWdfRequest->Complete(S_OK); + return; +} + +VOID +STDMETHODCALLTYPE +CSimdeviceQueue::OnWrite( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T BytesToWrite + ) +/*++ + +Routine Description: + + + Write dispatch routine + IQueueCallbackWrite + +Arguments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + BytesToWrite - Length of bytes in the write buffer + + Allocate and copy data to local buffer +Return Value: + + VOID + +--*/ +{ + + HRESULT hr; + IWDFMemory* pRequestMemory = NULL; + IWDFIoRequest2 * pWdfRequest2 = NULL; + + UNREFERENCED_PARAMETER(pWdfQueue); + + // + // Handle Zero length writes. + // + + if (!BytesToWrite) { + pWdfRequest->CompleteWithInformation(S_OK, 0); + return; + } + + if( BytesToWrite > MAX_WRITE_LENGTH ) { + + pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_MORE_DATA), 0); + return; + } + + // Get memory object + hr = pWdfRequest->QueryInterface(IID_PPV_ARGS(&pWdfRequest2)); + + if (FAILED(hr)) { + pWdfRequest->Complete(hr); + return; + } + + // Release previous buffer if set + + if( m_Buffer != NULL ) { + delete [] m_Buffer; + m_Buffer = NULL; + m_Length = 0L; + } + + // Allocate Buffer + + m_Buffer = new UCHAR[BytesToWrite]; + if (m_Buffer == NULL) { + pWdfRequest->Complete(E_OUTOFMEMORY); + m_Length = 0L; + return; + } + + hr = pWdfRequest2->RetrieveInputMemory(&pRequestMemory); + + if (FAILED(hr)) { + goto Exit; + } + + // Copy from memory object to our buffer + + hr = pRequestMemory->CopyToBuffer(0, m_Buffer, BytesToWrite); + + if (FAILED(hr)) { + goto Exit; + } + + + // + // Save the information so that we can use it + // to complete the request later. + // + + Lock(); + + m_Length = (ULONG) BytesToWrite; + m_XferredBytes = m_Length; + m_CurrentRequest = pWdfRequest2; + pWdfRequest2 = NULL; + + Unlock(); + +Exit: + + if (FAILED(hr)) { + pWdfRequest2->CompleteWithInformation(hr, 0); + delete [] m_Buffer; + m_Buffer = NULL; + } + + SAFE_RELEASE(pRequestMemory); + SAFE_RELEASE(pWdfRequest2); + + return; +} + +VOID +STDMETHODCALLTYPE +CSimdeviceQueue::OnRead( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T SizeInBytes + ) +/*++ + +Routine Description: + + + Read dispatch routine + IQueueCallbackRead + +Arguments: + + pWdfQueue - Framework Queue instance + pWdfRequest - Framework Request instance + SizeInBytes - Length of bytes in the read buffer + + Copy available data into the read buffer +Return Value: + + VOID + +--*/ +{ + IWDFMemory* pRequestMemory = NULL; + IWDFIoRequest2 * pWdfRequest2 = NULL; + HRESULT hr; + + UNREFERENCED_PARAMETER(pWdfQueue); + + // + // Handle Zero length reads. + // + + if (!SizeInBytes) { + pWdfRequest->CompleteWithInformation(S_OK, 0); + return; + } + + if (m_Buffer == NULL) { + pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), SizeInBytes); + return; + } + + if (m_Length < SizeInBytes) { + SizeInBytes = m_Length; + } + + // + // Get memory object + // + + hr = pWdfRequest->QueryInterface(IID_PPV_ARGS(&pWdfRequest2)); + + if (FAILED(hr)) { + pWdfRequest->Complete(hr); + return; + } + + + hr = pWdfRequest2->RetrieveOutputMemory(&pRequestMemory ); + + if (FAILED(hr)) { + goto Exit; + } + + // Copy from buffer to memory object + + hr = pRequestMemory->CopyFromBuffer(0, m_Buffer, SizeInBytes); + + if (FAILED(hr)) { + goto Exit; + } + + + // + // Save the information so that we can use it + // to complete the request later. + // + + Lock(); + + m_CurrentRequest = pWdfRequest2; + m_XferredBytes = SizeInBytes; + pWdfRequest2 = NULL; + + Unlock(); + +Exit: + + if (FAILED(hr)) { + pWdfRequest2->CompleteWithInformation(hr, 0); + } + + SAFE_RELEASE(pRequestMemory); + SAFE_RELEASE(pWdfRequest2); + return; +} + +DWORD +CSimdeviceQueue::CompletionThread( + PVOID ThreadParameter + ) +/*++ + +Routine Description: + + + This routine is called from the thread started to complete + I/O requests. It sleeps for TIMER_PERIOD and then completes + the current request. Note that it has to release the lock + before it calls the request complete method. + +Arguments: + + ThreadParameter - This is a pointer to the Queue object. + +Return Value: + + VOID + +--*/ +{ + CSimdeviceQueue *pQueue = (CSimdeviceQueue *)ThreadParameter; + IWDFIoRequest2 *request; + SIZE_T bytesXferred = 0; + + for (;;) { + + // + // Block for a fixed time and then complete the request. + // + + Sleep(TIMER_PERIOD); + + pQueue->Lock(); + + // + // Process the current request. + // + + request = pQueue->m_CurrentRequest; + + if (request) { + bytesXferred = pQueue->m_XferredBytes; + } + + // + // Reset values. + // + + pQueue->m_CurrentRequest = NULL; + pQueue->m_XferredBytes = 0; + + + pQueue->Unlock(); + + if (request) { + request->CompleteWithInformation(S_OK, bytesXferred); + SAFE_RELEASE(request); + } + + // + // If thread needs to be terminated + // + + if (pQueue->m_ExitThread) { + ExitThread(0); + } + + } + +} diff --git a/gpio/samples/simdeviceumdf/queue.h b/gpio/samples/simdeviceumdf/queue.h new file mode 100644 index 00000000..108299a4 --- /dev/null +++ b/gpio/samples/simdeviceumdf/queue.h @@ -0,0 +1,211 @@ +/*++ + +Copyright (c) Microsoft Corporation, All Rights Reserved + +Module Name: + + queue.h + +Abstract: + + This file defines the queue callback interface. + +Environment: + + Windows User-Mode Driver Framework (WUDF) + +--*/ + +#pragma once + +// Set max write length for testing +#define MAX_WRITE_LENGTH (40*1024) + +// Set timer period in ms +#define TIMER_PERIOD 100 + +// +// Queue Callback Object. +// + +class CSimdeviceQueue : + public IQueueCallbackDeviceIoControl, + public IQueueCallbackRead, + public IQueueCallbackWrite, + public CUnknown +{ + PVOID m_Buffer; // Current buffer + ULONG m_Length; // Length of the buffer + SIZE_T m_XferredBytes; // Amount of bytes transferred for the current request + IWDFIoRequest2 *m_CurrentRequest; // Current request + CRITICAL_SECTION m_Crit; // Lock to protect updates to CSimdeviceQueue fields + BOOLEAN m_ExitThread; // If TRUE Terminate thread. + BOOLEAN m_InitCritSec; // If TRUE lock initialized + + IWDFIoQueue *m_FxQueue; + + CSimdeviceQueue() : + m_Buffer(NULL), + m_Length (0), + m_CurrentRequest(NULL), + m_XferredBytes(0), + m_ExitThread(FALSE), + m_InitCritSec(FALSE), + m_FxQueue(NULL) + { + } + + virtual ~CSimdeviceQueue(); + + __inline + void + Lock( + ) + { + ::EnterCriticalSection(&m_Crit); + } + + __inline + void + Unlock( + ) + { + ::LeaveCriticalSection(&m_Crit); + } + + HRESULT + Initialize( + _In_ IWDFDevice *FxDevice + ); + +public: + + // + // Completion thread routine. + // + + static DWORD CompletionThread( PVOID ThreadParameter); + + // + // Sets the flag to make thread exit + // + + void + SetExitThread() + { + m_ExitThread = TRUE; + } + + static + HRESULT + CreateInstance( + _In_ IWDFDevice *FxDevice, + _Out_ PCSimdeviceQueue *Queue + ); + + HRESULT + Configure( + VOID + ) + { + return S_OK; + } + + + IQueueCallbackDeviceIoControl * + QueryIQueueCallbackDeviceIoControl( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackDeviceIoControl *>(this); + } + + IQueueCallbackRead * + QueryIQueueCallbackRead( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackRead *>(this); + } + + IQueueCallbackWrite * + QueryIQueueCallbackWrite( + VOID + ) + { + AddRef(); + return static_cast<IQueueCallbackWrite *>(this); + } + + // + // IUnknown + // + + virtual + ULONG + STDMETHODCALLTYPE + AddRef( + VOID + ) { + return CUnknown::AddRef(); + } + + __drv_arg(this, __drv_freesMem(object)) + virtual + ULONG + STDMETHODCALLTYPE + Release( + VOID + ) { + return CUnknown::Release(); + } + + virtual + HRESULT + STDMETHODCALLTYPE + QueryInterface( + _In_ REFIID InterfaceId, + _Out_ PVOID *Object + ); + + // + // Wdf Callbacks + // + + // IQueueCallbackDeviceIoControl + // + virtual + VOID + STDMETHODCALLTYPE + OnDeviceIoControl( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ ULONG ControlCode, + _In_ SIZE_T InputBufferSizeInBytes, + _In_ SIZE_T OutputBufferSizeInBytes + ); + + // IQueueCallbackWrite + // + virtual + VOID + STDMETHODCALLTYPE + OnWrite( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToWrite + ); + + // IQueueCallbackRead + // + virtual + VOID + STDMETHODCALLTYPE + OnRead( + _In_ IWDFIoQueue *pWdfQueue, + _In_ IWDFIoRequest *pWdfRequest, + _In_ SIZE_T NumOfBytesToRead + ); +}; diff --git a/gpio/samples/simdeviceumdf/simdeviceumdf.rc b/gpio/samples/simdeviceumdf/simdeviceumdf.rc new file mode 100644 index 00000000..8465960f --- /dev/null +++ b/gpio/samples/simdeviceumdf/simdeviceumdf.rc @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------- +// SimdeviceUMDF.rc +// +// Copyright (c) Microsoft Corporation, All Rights Reserved +//--------------------------------------------------------------------------- + + +#include <windows.h> +#include <ntverp.h> + +// +// TODO: Change the file description and file names to match your binary. +// + +#define VER_FILETYPE VFT_DLL +#define VER_FILESUBTYPE VFT_UNKNOWN +#define VER_FILEDESCRIPTION_STR "WDF:UMDF Simdevice User-Mode Driver Sample" +#define VER_INTERNALNAME_STR "SimdeviceUMDF" +#define VER_ORIGINALFILENAME_STR "SimdeviceUMDF.dll" + +#include "common.ver" diff --git a/gpio/samples/simdeviceumdf/simdeviceumdfdriver.ctl b/gpio/samples/simdeviceumdf/simdeviceumdfdriver.ctl new file mode 100644 index 00000000..a0ce2089 --- /dev/null +++ b/gpio/samples/simdeviceumdf/simdeviceumdfdriver.ctl @@ -0,0 +1 @@ +d93fb470-afb1-4af8-860e-75f726c66f6b WudfEchoDriverTraceGuid diff --git a/gpio/samples/simdeviceumdf/simdeviceumdfdriver.inx b/gpio/samples/simdeviceumdf/simdeviceumdfdriver.inx new file mode 100644 index 00000000..fa17b2bb --- /dev/null +++ b/gpio/samples/simdeviceumdf/simdeviceumdfdriver.inx @@ -0,0 +1,78 @@ +; +; SimdeviceUMDFDriver.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class=Sample +ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} +Provider=%MSFTWUDF% +CatalogFile=GpioSamples.cat +DriverVer=03/20/2003,5.00.3788 + +[Manufacturer] +%MSFTWUDF%=Microsoft,NT$ARCH$ + +[Microsoft.NT$ARCH$] +%SimdeviceUMDFName%=SimdeviceUMDF_Install,ACPI\TEST0004 + +[ClassInstall32] +AddReg=SampleClass_RegistryAdd + +[SampleClass_RegistryAdd] +HKR,,,,%ClassName% +HKR,,Icon,,"-10" + +[SourceDisksFiles] +SimdeviceUMDF.dll=1 + +[SourceDisksNames] +1 = %MediaDescription% + +; =================== Simdevice Sample UMDF Driver ================================== + +[SimdeviceUMDF_Install.NT] +CopyFiles=UMDriverCopy + +[SimdeviceUMDF_Install.NT.hw] + +[SimdeviceUMDF_Install.NT.Services] +AddService=SimdeviceUMDF,0x000001fa,SimdeviceUMDF_ServiceInstall + +[SimdeviceUMDF_Install.NT.Wdf] +UmdfService=SimdeviceUMDF,SimdeviceUMDF_Install +UmdfServiceOrder=SimdeviceUMDF + +; this enables direct hardware access from UMDF driver +UmdfDirectHardwareAccess=AllowDirectHardwareAccess + +; direct i/o devices cannot run in default pool. +UmdfHostProcessSharing=ProcessSharingDisabled + +[SimdeviceUMDF_Install] +UmdfLibraryVersion=$UMDFVERSION$ +DriverCLSID={7AB7DCF5-D1D4-4085-9547-1DB968CCA720} +ServiceBinary=%12%\UMDF\SimdeviceUMDF.dll + +[SimdeviceUMDF_ServiceInstall] +DisplayName = %SimdeviceUMDFDisplayName% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WUDFRd.sys + +[DestinationDirs] +UMDriverCopy=12,UMDF ; copy to drivers\UMDF +CoInstallers_CopyFiles=11 + +[UMDriverCopy] +SimdeviceUMDF.dll + +; =================== Generic ================================== + +[Strings] +MSFTWUDF="Microsoft Internal (WUDF)" +MediaDescription="Microsoft WUDF Sample Driver Installation Media" +ClassName="Sample Device" +SimdeviceUMDFDisplayName="Sample User-mode Driver Framework Reflector driver" +SimdeviceUMDFName="Sample device UMDF Driver" |
