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 /general/ioctl | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'general/ioctl')
| -rw-r--r-- | general/ioctl/wdm/ReadMe.md | 17 | ||||
| -rw-r--r-- | general/ioctl/wdm/exe/install.c | 550 | ||||
| -rw-r--r-- | general/ioctl/wdm/exe/ioctlapp.vcxproj | 196 | ||||
| -rw-r--r-- | general/ioctl/wdm/exe/ioctlapp.vcxproj.Filters | 25 | ||||
| -rw-r--r-- | general/ioctl/wdm/exe/testapp.c | 261 | ||||
| -rw-r--r-- | general/ioctl/wdm/ioctl.sln | 46 | ||||
| -rw-r--r-- | general/ioctl/wdm/sys/sioctl.c | 744 | ||||
| -rw-r--r-- | general/ioctl/wdm/sys/sioctl.h | 47 | ||||
| -rw-r--r-- | general/ioctl/wdm/sys/sioctl.rc | 10 | ||||
| -rw-r--r-- | general/ioctl/wdm/sys/sioctl.vcxproj | 140 | ||||
| -rw-r--r-- | general/ioctl/wdm/sys/sioctl.vcxproj.Filters | 31 |
11 files changed, 2067 insertions, 0 deletions
diff --git a/general/ioctl/wdm/ReadMe.md b/general/ioctl/wdm/ReadMe.md new file mode 100644 index 00000000..94191a33 --- /dev/null +++ b/general/ioctl/wdm/ReadMe.md @@ -0,0 +1,17 @@ +IOCTL +===== + +This sample demonstrates the usage of four different types of IOCTLs (METHOD\_IN\_DIRECT, METHOD\_OUT\_DIRECT, METHOD\_NEITHER, and METHOD\_BUFFERED). + +The sample shows how the user input and output buffers specified in the **DeviceIoControl** function call are handled, in each case, by the I/O subsystem and the driver. + +The sample consists of a legacy device driver and a Win32 console test application. The test application opens a handle to the device exposed by the driver and makes all four different **DeviceIoControl** calls, one after another. To understand how the IRP fields are set the I/O manager, you should run the checked build version of the driver and look at the debug output. + +**Note** This sample driver is not a Plug and Play driver. This is a minimal driver meant to demonstrate a feature of the operating system. Neither this driver nor its sample programs are intended for use in a production environment. Instead, they are intended for educational purposes and as a skeleton driver. + + +Run the sample +-------------- + +To test this driver, copy the test app, Ioctlapp.exe, and the driver to the same directory, and run the application. The application will automatically load the driver, if it's not already loaded, and interact with the driver. When you exit the application, the driver will be stopped, unloaded and removed. + diff --git a/general/ioctl/wdm/exe/install.c b/general/ioctl/wdm/exe/install.c new file mode 100644 index 00000000..4b77f0aa --- /dev/null +++ b/general/ioctl/wdm/exe/install.c @@ -0,0 +1,550 @@ +/*++ +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: + + install.c + +Abstract: + + Win32 routines to dynamically load and unload a Windows NT kernel-mode + driver using the Service Control Manager APIs. + +Environment: + + User mode only + +--*/ + + +#include <windows.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strsafe.h> +#include "sioctl.h" + +BOOLEAN +InstallDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName, + _In_ LPCTSTR ServiceExe + ); + + +BOOLEAN +RemoveDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ); + +BOOLEAN +StartDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ); + +BOOLEAN +StopDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ); + +BOOLEAN +InstallDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName, + _In_ LPCTSTR ServiceExe + ) +/*++ + +Routine Description: + +Arguments: + +Return Value: + +--*/ +{ + SC_HANDLE schService; + DWORD err; + + // + // NOTE: This creates an entry for a standalone driver. If this + // is modified for use with a driver that requires a Tag, + // Group, and/or Dependencies, it may be necessary to + // query the registry for existing driver information + // (in order to determine a unique Tag, etc.). + // + + // + // Create a new a service object. + // + + schService = CreateService(SchSCManager, // handle of service control manager database + DriverName, // address of name of service to start + DriverName, // address of display name + SERVICE_ALL_ACCESS, // type of access to service + SERVICE_KERNEL_DRIVER, // type of service + SERVICE_DEMAND_START, // when to start service + SERVICE_ERROR_NORMAL, // severity if service fails to start + ServiceExe, // address of name of binary file + NULL, // service does not belong to a group + NULL, // no tag requested + NULL, // no dependency names + NULL, // use LocalSystem account + NULL // no password for service account + ); + + if (schService == NULL) { + + err = GetLastError(); + + if (err == ERROR_SERVICE_EXISTS) { + + // + // Ignore this error. + // + + return TRUE; + + } else { + + printf("CreateService failed! Error = %d \n", err ); + + // + // Indicate an error. + // + + return FALSE; + } + } + + // + // Close the service object. + // + + if (schService) { + + CloseServiceHandle(schService); + } + + // + // Indicate success. + // + + return TRUE; + +} // InstallDriver + +BOOLEAN +ManageDriver( + _In_ LPCTSTR DriverName, + _In_ LPCTSTR ServiceName, + _In_ USHORT Function + ) +{ + + SC_HANDLE schSCManager; + + BOOLEAN rCode = TRUE; + + // + // Insure (somewhat) that the driver and service names are valid. + // + + if (!DriverName || !ServiceName) { + + printf("Invalid Driver or Service provided to ManageDriver() \n"); + + return FALSE; + } + + // + // Connect to the Service Control Manager and open the Services database. + // + + schSCManager = OpenSCManager(NULL, // local machine + NULL, // local database + SC_MANAGER_ALL_ACCESS // access required + ); + + if (!schSCManager) { + + printf("Open SC Manager failed! Error = %d \n", GetLastError()); + + return FALSE; + } + + // + // Do the requested function. + // + + switch( Function ) { + + case DRIVER_FUNC_INSTALL: + + // + // Install the driver service. + // + + if (InstallDriver(schSCManager, + DriverName, + ServiceName + )) { + + // + // Start the driver service (i.e. start the driver). + // + + rCode = StartDriver(schSCManager, + DriverName + ); + + } else { + + // + // Indicate an error. + // + + rCode = FALSE; + } + + break; + + case DRIVER_FUNC_REMOVE: + + // + // Stop the driver. + // + + StopDriver(schSCManager, + DriverName + ); + + // + // Remove the driver service. + // + + RemoveDriver(schSCManager, + DriverName + ); + + // + // Ignore all errors. + // + + rCode = TRUE; + + break; + + default: + + printf("Unknown ManageDriver() function. \n"); + + rCode = FALSE; + + break; + } + + // + // Close handle to service control manager. + // + + if (schSCManager) { + + CloseServiceHandle(schSCManager); + } + + return rCode; + +} // ManageDriver + + +BOOLEAN +RemoveDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ) +{ + SC_HANDLE schService; + BOOLEAN rCode; + + // + // Open the handle to the existing service. + // + + schService = OpenService(SchSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) { + + printf("OpenService failed! Error = %d \n", GetLastError()); + + // + // Indicate error. + // + + return FALSE; + } + + // + // Mark the service for deletion from the service control manager database. + // + + if (DeleteService(schService)) { + + // + // Indicate success. + // + + rCode = TRUE; + + } else { + + printf("DeleteService failed! Error = %d \n", GetLastError()); + + // + // Indicate failure. Fall through to properly close the service handle. + // + + rCode = FALSE; + } + + // + // Close the service object. + // + + if (schService) { + + CloseServiceHandle(schService); + } + + return rCode; + +} // RemoveDriver + + + +BOOLEAN +StartDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ) +{ + SC_HANDLE schService; + DWORD err; + + // + // Open the handle to the existing service. + // + + schService = OpenService(SchSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) { + + printf("OpenService failed! Error = %d \n", GetLastError()); + + // + // Indicate failure. + // + + return FALSE; + } + + // + // Start the execution of the service (i.e. start the driver). + // + + if (!StartService(schService, // service identifier + 0, // number of arguments + NULL // pointer to arguments + )) { + + err = GetLastError(); + + if (err == ERROR_SERVICE_ALREADY_RUNNING) { + + // + // Ignore this error. + // + + return TRUE; + + } else { + + printf("StartService failure! Error = %d \n", err ); + + // + // Indicate failure. Fall through to properly close the service handle. + // + + return FALSE; + } + + } + + // + // Close the service object. + // + + if (schService) { + + CloseServiceHandle(schService); + } + + return TRUE; + +} // StartDriver + + + +BOOLEAN +StopDriver( + _In_ SC_HANDLE SchSCManager, + _In_ LPCTSTR DriverName + ) +{ + BOOLEAN rCode = TRUE; + SC_HANDLE schService; + SERVICE_STATUS serviceStatus; + + // + // Open the handle to the existing service. + // + + schService = OpenService(SchSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) { + + printf("OpenService failed! Error = %d \n", GetLastError()); + + return FALSE; + } + + // + // Request that the service stop. + // + + if (ControlService(schService, + SERVICE_CONTROL_STOP, + &serviceStatus + )) { + + // + // Indicate success. + // + + rCode = TRUE; + + } else { + + printf("ControlService failed! Error = %d \n", GetLastError() ); + + // + // Indicate failure. Fall through to properly close the service handle. + // + + rCode = FALSE; + } + + // + // Close the service object. + // + + if (schService) { + + CloseServiceHandle (schService); + } + + return rCode; + +} // StopDriver + +BOOLEAN +SetupDriverName( + _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation, + _In_ ULONG BufferLength + ) +{ + HANDLE fileHandle; + DWORD driverLocLen = 0; + + // + // Get the current directory. + // + + driverLocLen = GetCurrentDirectory(BufferLength, + DriverLocation + ); + + if (driverLocLen == 0) { + + printf("GetCurrentDirectory failed! Error = %d \n", GetLastError()); + + return FALSE; + } + + // + // Setup path name to driver file. + // + if (FAILED( StringCbCat(DriverLocation, BufferLength, "\\"DRIVER_NAME".sys") )) { + return FALSE; + } + + // + // Insure driver file is in the specified directory. + // + + if ((fileHandle = CreateFile(DriverLocation, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + )) == INVALID_HANDLE_VALUE) { + + + printf("%s.sys is not loaded.\n", DRIVER_NAME); + + // + // Indicate failure. + // + + return FALSE; + } + + // + // Close open file handle. + // + + if (fileHandle) { + + CloseHandle(fileHandle); + } + + // + // Indicate success. + // + + return TRUE; + + +} // SetupDriverName + + + diff --git a/general/ioctl/wdm/exe/ioctlapp.vcxproj b/general/ioctl/wdm/exe/ioctlapp.vcxproj new file mode 100644 index 00000000..976df289 --- /dev/null +++ b/general/ioctl/wdm/exe/ioctlapp.vcxproj @@ -0,0 +1,196 @@ +<?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>{76D71F31-1E96-453B-B624-603110936517}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{F11B90FF-7C0F-4187-A69C-B3D2C6FA36BD}</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 /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>Application</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" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>ioctlapp</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>ioctlapp</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>ioctlapp</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>ioctlapp</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </Midl> + <Link> + <BaseAddress>0x04000000</BaseAddress> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </Midl> + <Link> + <BaseAddress>0x04000000</BaseAddress> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </Midl> + <Link> + <BaseAddress>0x04000000</BaseAddress> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ClCompile> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </ResourceCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\sys</AdditionalIncludeDirectories> + </Midl> + <Link> + <BaseAddress>0x04000000</BaseAddress> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="install.c" /> + <ClCompile Include="testapp.c" /> + </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/general/ioctl/wdm/exe/ioctlapp.vcxproj.Filters b/general/ioctl/wdm/exe/ioctlapp.vcxproj.Filters new file mode 100644 index 00000000..6698bc65 --- /dev/null +++ b/general/ioctl/wdm/exe/ioctlapp.vcxproj.Filters @@ -0,0 +1,25 @@ +<?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>{A6129EF0-0D42-48B8-B0C4-C484D8CB1BEC}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{7C1B93C7-3641-4D37-AF76-8B4E72FB0E36}</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>{4E2B024A-1EF5-41B1-A019-C74272815D2A}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="install.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="testapp.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/general/ioctl/wdm/exe/testapp.c b/general/ioctl/wdm/exe/testapp.c new file mode 100644 index 00000000..5a62faa0 --- /dev/null +++ b/general/ioctl/wdm/exe/testapp.c @@ -0,0 +1,261 @@ +/*++ + +Copyright (c) 1990-98 Microsoft Corporation All Rights Reserved + +Module Name: + + testapp.c + +Abstract: + +Environment: + + Win32 console multi-threaded application + +--*/ +#include <windows.h> +#include <winioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strsafe.h> +#include "..\sys\sioctl.h" + + +BOOLEAN +ManageDriver( + _In_ LPCTSTR DriverName, + _In_ LPCTSTR ServiceName, + _In_ USHORT Function + ); + +BOOLEAN +SetupDriverName( + _Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation, + _In_ ULONG BufferLength + ); + +char OutputBuffer[100]; +char InputBuffer[100]; + +VOID __cdecl +main( + _In_ ULONG argc, + _In_reads_(argc) PCHAR argv[] + ) +{ + HANDLE hDevice; + BOOL bRc; + ULONG bytesReturned; + DWORD errNum = 0; + TCHAR driverLocation[MAX_PATH]; + + UNREFERENCED_PARAMETER(argc); + UNREFERENCED_PARAMETER(argv); + + // + // open the device + // + + if ((hDevice = CreateFile( "\\\\.\\IoctlTest", + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) { + + errNum = GetLastError(); + + if (errNum != ERROR_FILE_NOT_FOUND) { + + printf("CreateFile failed! ERROR_FILE_NOT_FOUND = %d\n", errNum); + + return ; + } + + // + // The driver is not started yet so let us the install the driver. + // First setup full path to driver name. + // + + if (!SetupDriverName(driverLocation, sizeof(driverLocation))) { + + return ; + } + + if (!ManageDriver(DRIVER_NAME, + driverLocation, + DRIVER_FUNC_INSTALL + )) { + + printf("Unable to install driver. \n"); + + // + // Error - remove driver. + // + + ManageDriver(DRIVER_NAME, + driverLocation, + DRIVER_FUNC_REMOVE + ); + + return; + } + + hDevice = CreateFile( "\\\\.\\IoctlTest", + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if ( hDevice == INVALID_HANDLE_VALUE ){ + printf ( "Error: CreatFile Failed : %d\n", GetLastError()); + return; + } + + } + + // + // Printing Input & Output buffer pointers and size + // + + printf("InputBuffer Pointer = %p, BufLength = %d\n", InputBuffer, + sizeof(InputBuffer)); + printf("OutputBuffer Pointer = %p BufLength = %d\n", OutputBuffer, + sizeof(OutputBuffer)); + // + // Performing METHOD_BUFFERED + // + + StringCbCopy(InputBuffer, sizeof(InputBuffer), + "This String is from User Application; using METHOD_BUFFERED"); + + printf("\nCalling DeviceIoControl METHOD_BUFFERED:\n"); + + memset(OutputBuffer, 0, sizeof(OutputBuffer)); + + bRc = DeviceIoControl ( hDevice, + (DWORD) IOCTL_SIOCTL_METHOD_BUFFERED, + &InputBuffer, + (DWORD) strlen ( InputBuffer )+1, + &OutputBuffer, + sizeof( OutputBuffer), + &bytesReturned, + NULL + ); + + if ( !bRc ) + { + printf ( "Error in DeviceIoControl : %d", GetLastError()); + return; + + } + printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer); + + // + // Performing METHOD_NIETHER + // + + printf("\nCalling DeviceIoControl METHOD_NEITHER\n"); + + StringCbCopy(InputBuffer, sizeof(InputBuffer), + "This String is from User Application; using METHOD_NEITHER"); + memset(OutputBuffer, 0, sizeof(OutputBuffer)); + + bRc = DeviceIoControl ( hDevice, + (DWORD) IOCTL_SIOCTL_METHOD_NEITHER, + &InputBuffer, + (DWORD) strlen ( InputBuffer )+1, + &OutputBuffer, + sizeof( OutputBuffer), + &bytesReturned, + NULL + ); + + if ( !bRc ) + { + printf ( "Error in DeviceIoControl : %d\n", GetLastError()); + return; + + } + + printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer); + + // + // Performing METHOD_IN_DIRECT + // + + printf("\nCalling DeviceIoControl METHOD_IN_DIRECT\n"); + + StringCbCopy(InputBuffer, sizeof(InputBuffer), + "This String is from User Application; using METHOD_IN_DIRECT"); + StringCbCopy(OutputBuffer, sizeof(OutputBuffer), + "This String is from User Application in OutBuffer; using METHOD_IN_DIRECT"); + + bRc = DeviceIoControl ( hDevice, + (DWORD) IOCTL_SIOCTL_METHOD_IN_DIRECT, + &InputBuffer, + (DWORD) strlen ( InputBuffer )+1, + &OutputBuffer, + sizeof( OutputBuffer), + &bytesReturned, + NULL + ); + + if ( !bRc ) + { + printf ( "Error in DeviceIoControl : : %d", GetLastError()); + return; + } + + printf(" Number of bytes transfered from OutBuffer: %d\n", + bytesReturned); + + // + // Performing METHOD_OUT_DIRECT + // + + printf("\nCalling DeviceIoControl METHOD_OUT_DIRECT\n"); + StringCbCopy(InputBuffer, sizeof(InputBuffer), + "This String is from User Application; using METHOD_OUT_DIRECT"); + memset(OutputBuffer, 0, sizeof(OutputBuffer)); + bRc = DeviceIoControl ( hDevice, + (DWORD) IOCTL_SIOCTL_METHOD_OUT_DIRECT, + &InputBuffer, + (DWORD) strlen ( InputBuffer )+1, + &OutputBuffer, + sizeof( OutputBuffer), + &bytesReturned, + NULL + ); + + if ( !bRc ) + { + printf ( "Error in DeviceIoControl : : %d", GetLastError()); + return; + } + + printf(" OutBuffer (%d): %s\n", bytesReturned, OutputBuffer); + + CloseHandle ( hDevice ); + + // + // Unload the driver. Ignore any errors. + // + + ManageDriver(DRIVER_NAME, + driverLocation, + DRIVER_FUNC_REMOVE + ); + + + // + // close the handle to the device. + // + +} + + diff --git a/general/ioctl/wdm/ioctl.sln b/general/ioctl/wdm/ioctl.sln new file mode 100644 index 00000000..ba787f9d --- /dev/null +++ b/general/ioctl/wdm/ioctl.sln @@ -0,0 +1,46 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0 +MinimumVisualStudioVersion = 12.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{91C983A9-7E97-4964-A924-F019A135772F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sys", "Sys", "{9D017694-F9BE-450B-BF96-67F46D45BE81}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ioctlapp", "exe\ioctlapp.vcxproj", "{76D71F31-1E96-453B-B624-603110936517}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sioctl", "sys\sioctl.vcxproj", "{EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {76D71F31-1E96-453B-B624-603110936517}.Debug|Win32.ActiveCfg = Debug|Win32 + {76D71F31-1E96-453B-B624-603110936517}.Debug|Win32.Build.0 = Debug|Win32 + {76D71F31-1E96-453B-B624-603110936517}.Release|Win32.ActiveCfg = Release|Win32 + {76D71F31-1E96-453B-B624-603110936517}.Release|Win32.Build.0 = Release|Win32 + {76D71F31-1E96-453B-B624-603110936517}.Debug|x64.ActiveCfg = Debug|x64 + {76D71F31-1E96-453B-B624-603110936517}.Debug|x64.Build.0 = Debug|x64 + {76D71F31-1E96-453B-B624-603110936517}.Release|x64.ActiveCfg = Release|x64 + {76D71F31-1E96-453B-B624-603110936517}.Release|x64.Build.0 = Release|x64 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Debug|Win32.ActiveCfg = Debug|Win32 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Debug|Win32.Build.0 = Debug|Win32 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Release|Win32.ActiveCfg = Release|Win32 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Release|Win32.Build.0 = Release|Win32 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Debug|x64.ActiveCfg = Debug|x64 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Debug|x64.Build.0 = Debug|x64 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Release|x64.ActiveCfg = Release|x64 + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {76D71F31-1E96-453B-B624-603110936517} = {91C983A9-7E97-4964-A924-F019A135772F} + {EFC79CFC-9D17-4830-90C1-1825B6CFE1AD} = {9D017694-F9BE-450B-BF96-67F46D45BE81} + EndGlobalSection +EndGlobal diff --git a/general/ioctl/wdm/sys/sioctl.c b/general/ioctl/wdm/sys/sioctl.c new file mode 100644 index 00000000..7eae2971 --- /dev/null +++ b/general/ioctl/wdm/sys/sioctl.c @@ -0,0 +1,744 @@ +/*++ + +Copyright (c) 1990-98 Microsoft Corporation All Rights Reserved + +Module Name: + + sioctl.c + +Abstract: + + Purpose of this driver is to demonstrate how the four different types + of IOCTLs can be used, and how the I/O manager handles the user I/O + buffers in each case. This sample also helps to understand the usage of + some of the memory manager functions. + +Environment: + + Kernel mode only. + +--*/ + + +// +// Include files. +// + +#include <ntddk.h> // various NT definitions +#include <string.h> + +#include "sioctl.h" + +#define NT_DEVICE_NAME L"\\Device\\SIOCTL" +#define DOS_DEVICE_NAME L"\\DosDevices\\IoctlTest" + +#if DBG +#define SIOCTL_KDPRINT(_x_) \ + DbgPrint("SIOCTL.SYS: ");\ + DbgPrint _x_; + +#else +#define SIOCTL_KDPRINT(_x_) +#endif + +// +// Device driver routine declarations. +// + +DRIVER_INITIALIZE DriverEntry; + +_Dispatch_type_(IRP_MJ_CREATE) +_Dispatch_type_(IRP_MJ_CLOSE) +DRIVER_DISPATCH SioctlCreateClose; + +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +DRIVER_DISPATCH SioctlDeviceControl; + +DRIVER_UNLOAD SioctlUnloadDriver; + +VOID +PrintIrpInfo( + PIRP Irp + ); +VOID +PrintChars( + _In_reads_(CountChars) PCHAR BufferAddress, + _In_ size_t CountChars + ); + +#ifdef ALLOC_PRAGMA +#pragma alloc_text( INIT, DriverEntry ) +#pragma alloc_text( PAGE, SioctlCreateClose) +#pragma alloc_text( PAGE, SioctlDeviceControl) +#pragma alloc_text( PAGE, SioctlUnloadDriver) +#pragma alloc_text( PAGE, PrintIrpInfo) +#pragma alloc_text( PAGE, PrintChars) +#endif // ALLOC_PRAGMA + + +NTSTATUS +DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +/*++ + +Routine Description: + This routine is called by the Operating System to initialize the driver. + + It creates the device object, fills in the dispatch entry points and + completes the initialization. + +Arguments: + DriverObject - a pointer to the object that represents this device + driver. + + RegistryPath - a pointer to our Services key in the registry. + +Return Value: + STATUS_SUCCESS if initialized; an error otherwise. + +--*/ + +{ + NTSTATUS ntStatus; + UNICODE_STRING ntUnicodeString; // NT Device Name "\Device\SIOCTL" + UNICODE_STRING ntWin32NameString; // Win32 Name "\DosDevices\IoctlTest" + PDEVICE_OBJECT deviceObject = NULL; // ptr to device object + + UNREFERENCED_PARAMETER(RegistryPath); + + RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME ); + + ntStatus = IoCreateDevice( + DriverObject, // Our Driver Object + 0, // We don't use a device extension + &ntUnicodeString, // Device name "\Device\SIOCTL" + FILE_DEVICE_UNKNOWN, // Device type + FILE_DEVICE_SECURE_OPEN, // Device characteristics + FALSE, // Not an exclusive device + &deviceObject ); // Returned ptr to Device Object + + if ( !NT_SUCCESS( ntStatus ) ) + { + SIOCTL_KDPRINT(("Couldn't create the device object\n")); + return ntStatus; + } + + // + // Initialize the driver object with this driver's entry points. + // + + DriverObject->MajorFunction[IRP_MJ_CREATE] = SioctlCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = SioctlCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SioctlDeviceControl; + DriverObject->DriverUnload = SioctlUnloadDriver; + + // + // Initialize a Unicode String containing the Win32 name + // for our device. + // + + RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME ); + + // + // Create a symbolic link between our device name and the Win32 name + // + + ntStatus = IoCreateSymbolicLink( + &ntWin32NameString, &ntUnicodeString ); + + if ( !NT_SUCCESS( ntStatus ) ) + { + // + // Delete everything that this routine has allocated. + // + SIOCTL_KDPRINT(("Couldn't create symbolic link\n")); + IoDeleteDevice( deviceObject ); + } + + + return ntStatus; +} + + +NTSTATUS +SioctlCreateClose( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) +/*++ + +Routine Description: + + This routine is called by the I/O system when the SIOCTL is opened or + closed. + + No action is performed other than completing the request successfully. + +Arguments: + + DeviceObject - a pointer to the object that represents the device + that I/O is to be done on. + + Irp - a pointer to the I/O Request Packet for this request. + +Return Value: + + NT status code + +--*/ + +{ + UNREFERENCED_PARAMETER(DeviceObject); + + PAGED_CODE(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + + return STATUS_SUCCESS; +} + +VOID +SioctlUnloadDriver( + _In_ PDRIVER_OBJECT DriverObject + ) +/*++ + +Routine Description: + + This routine is called by the I/O system to unload the driver. + + Any resources previously allocated must be freed. + +Arguments: + + DriverObject - a pointer to the object that represents our driver. + +Return Value: + + None +--*/ + +{ + PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; + UNICODE_STRING uniWin32NameString; + + PAGED_CODE(); + + // + // Create counted string version of our Win32 device name. + // + + RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME ); + + + // + // Delete the link from our device name to a name in the Win32 namespace. + // + + IoDeleteSymbolicLink( &uniWin32NameString ); + + if ( deviceObject != NULL ) + { + IoDeleteDevice( deviceObject ); + } + + + +} + +NTSTATUS +SioctlDeviceControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) + +/*++ + +Routine Description: + + This routine is called by the I/O system to perform a device I/O + control function. + +Arguments: + + DeviceObject - a pointer to the object that represents the device + that I/O is to be done on. + + Irp - a pointer to the I/O Request Packet for this request. + +Return Value: + + NT status code + +--*/ + +{ + PIO_STACK_LOCATION irpSp;// Pointer to current stack location + NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success + ULONG inBufLength; // Input buffer length + ULONG outBufLength; // Output buffer length + PCHAR inBuf, outBuf; // pointer to Input and output buffer + PCHAR data = "This String is from Device Driver !!!"; + size_t datalen = strlen(data)+1;//Length of data including null + PMDL mdl = NULL; + PCHAR buffer = NULL; + + UNREFERENCED_PARAMETER(DeviceObject); + + PAGED_CODE(); + + irpSp = IoGetCurrentIrpStackLocation( Irp ); + inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; + outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength; + + if (!inBufLength || !outBufLength) + { + ntStatus = STATUS_INVALID_PARAMETER; + goto End; + } + + // + // Determine which I/O control code was specified. + // + + switch ( irpSp->Parameters.DeviceIoControl.IoControlCode ) + { + case IOCTL_SIOCTL_METHOD_BUFFERED: + + // + // In this method the I/O manager allocates a buffer large enough to + // to accommodate larger of the user input buffer and output buffer, + // assigns the address to Irp->AssociatedIrp.SystemBuffer, and + // copies the content of the user input buffer into this SystemBuffer + // + + SIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_BUFFERED\n")); + PrintIrpInfo(Irp); + + // + // Input buffer and output buffer is same in this case, read the + // content of the buffer before writing to it + // + + inBuf = Irp->AssociatedIrp.SystemBuffer; + outBuf = Irp->AssociatedIrp.SystemBuffer; + + // + // Read the data from the buffer + // + + SIOCTL_KDPRINT(("\tData from User :")); + // + // We are using the following function to print characters instead + // DebugPrint with %s format because we string we get may or + // may not be null terminated. + // + PrintChars(inBuf, inBufLength); + + // + // Write to the buffer over-writes the input buffer content + // + + RtlCopyBytes(outBuf, data, outBufLength); + + SIOCTL_KDPRINT(("\tData to User : ")); + PrintChars(outBuf, datalen ); + + // + // Assign the length of the data copied to IoStatus.Information + // of the Irp and complete the Irp. + // + + Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen); + + // + // When the Irp is completed the content of the SystemBuffer + // is copied to the User output buffer and the SystemBuffer is + // is freed. + // + + break; + + case IOCTL_SIOCTL_METHOD_NEITHER: + + // + // In this type of transfer the I/O manager assigns the user input + // to Type3InputBuffer and the output buffer to UserBuffer of the Irp. + // The I/O manager doesn't copy or map the buffers to the kernel + // buffers. Nor does it perform any validation of user buffer's address + // range. + // + + + SIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_NEITHER\n")); + + PrintIrpInfo(Irp); + + // + // A driver may access these buffers directly if it is a highest level + // driver whose Dispatch routine runs in the context + // of the thread that made this request. The driver should always + // check the validity of the user buffer's address range and check whether + // the appropriate read or write access is permitted on the buffer. + // It must also wrap its accesses to the buffer's address range within + // an exception handler in case another user thread deallocates the buffer + // or attempts to change the access rights for the buffer while the driver + // is accessing memory. + // + + inBuf = irpSp->Parameters.DeviceIoControl.Type3InputBuffer; + outBuf = Irp->UserBuffer; + + // + // Access the buffers directly if only if you are running in the + // context of the calling process. Only top level drivers are + // guaranteed to have the context of process that made the request. + // + + try { + // + // Before accessing user buffer, you must probe for read/write + // to make sure the buffer is indeed an userbuffer with proper access + // rights and length. ProbeForRead/Write will raise an exception if it's otherwise. + // + ProbeForRead( inBuf, inBufLength, sizeof( UCHAR ) ); + + // + // Since the buffer access rights can be changed or buffer can be freed + // anytime by another thread of the same process, you must always access + // it within an exception handler. + // + + SIOCTL_KDPRINT(("\tData from User :")); + PrintChars(inBuf, inBufLength); + + } + except(EXCEPTION_EXECUTE_HANDLER) + { + + ntStatus = GetExceptionCode(); + SIOCTL_KDPRINT(( + "Exception while accessing inBuf 0X%08X in METHOD_NEITHER\n", + ntStatus)); + break; + } + + + // + // If you are accessing these buffers in an arbitrary thread context, + // say in your DPC or ISR, if you are using it for DMA, or passing these buffers to the + // next level driver, you should map them in the system process address space. + // First allocate an MDL large enough to describe the buffer + // and initilize it. Please note that on a x86 system, the maximum size of a buffer + // that an MDL can describe is 65508 KB. + // + + mdl = IoAllocateMdl(inBuf, inBufLength, FALSE, TRUE, NULL); + if (!mdl) + { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + try + { + + // + // Probe and lock the pages of this buffer in physical memory. + // You can specify IoReadAccess, IoWriteAccess or IoModifyAccess + // Always perform this operation in a try except block. + // MmProbeAndLockPages will raise an exception if it fails. + // + MmProbeAndLockPages(mdl, UserMode, IoReadAccess); + } + except(EXCEPTION_EXECUTE_HANDLER) + { + + ntStatus = GetExceptionCode(); + SIOCTL_KDPRINT(( + "Exception while locking inBuf 0X%08X in METHOD_NEITHER\n", + ntStatus)); + IoFreeMdl(mdl); + break; + } + + // + // Map the physical pages described by the MDL into system space. + // Note: double mapping the buffer this way causes lot of + // system overhead for large size buffers. + // + + buffer = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority ); + + if (!buffer) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + MmUnlockPages(mdl); + IoFreeMdl(mdl); + break; + } + + // + // Now you can safely read the data from the buffer. + // + SIOCTL_KDPRINT(("\tData from User (SystemAddress) : ")); + PrintChars(buffer, inBufLength); + + // + // Once the read is over unmap and unlock the pages. + // + + MmUnlockPages(mdl); + IoFreeMdl(mdl); + + // + // The same steps can be followed to access the output buffer. + // + + mdl = IoAllocateMdl(outBuf, outBufLength, FALSE, TRUE, NULL); + if (!mdl) + { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + + try { + // + // Probe and lock the pages of this buffer in physical memory. + // You can specify IoReadAccess, IoWriteAccess or IoModifyAccess. + // + + MmProbeAndLockPages(mdl, UserMode, IoWriteAccess); + } + except(EXCEPTION_EXECUTE_HANDLER) + { + + ntStatus = GetExceptionCode(); + SIOCTL_KDPRINT(( + "Exception while locking outBuf 0X%08X in METHOD_NEITHER\n", + ntStatus)); + IoFreeMdl(mdl); + break; + } + + + buffer = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority ); + + if (!buffer) { + MmUnlockPages(mdl); + IoFreeMdl(mdl); + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + break; + } + // + // Write to the buffer + // + + RtlCopyBytes(buffer, data, outBufLength); + + SIOCTL_KDPRINT(("\tData to User : %s\n", buffer)); + PrintChars(buffer, datalen); + + MmUnlockPages(mdl); + + // + // Free the allocated MDL + // + + IoFreeMdl(mdl); + + // + // Assign the length of the data copied to IoStatus.Information + // of the Irp and complete the Irp. + // + + Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen); + + break; + + case IOCTL_SIOCTL_METHOD_IN_DIRECT: + + // + // In this type of transfer, the I/O manager allocates a system buffer + // large enough to accommodatethe User input buffer, sets the buffer address + // in Irp->AssociatedIrp.SystemBuffer and copies the content of user input buffer + // into the SystemBuffer. For the user output buffer, the I/O manager + // probes to see whether the virtual address is readable in the callers + // access mode, locks the pages in memory and passes the pointer to + // MDL describing the buffer in Irp->MdlAddress. + // + + SIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_IN_DIRECT\n")); + + PrintIrpInfo(Irp); + + inBuf = Irp->AssociatedIrp.SystemBuffer; + + SIOCTL_KDPRINT(("\tData from User in InputBuffer: ")); + PrintChars(inBuf, inBufLength); + + // + // To access the output buffer, just get the system address + // for the buffer. For this method, this buffer is intended for transfering data + // from the application to the driver. + // + + buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + + if (!buffer) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + SIOCTL_KDPRINT(("\tData from User in OutputBuffer: ")); + PrintChars(buffer, outBufLength); + + // + // Return total bytes read from the output buffer. + // Note OutBufLength = MmGetMdlByteCount(Irp->MdlAddress) + // + + Irp->IoStatus.Information = MmGetMdlByteCount(Irp->MdlAddress); + + // + // NOTE: Changes made to the SystemBuffer are not copied + // to the user input buffer by the I/O manager + // + + break; + + case IOCTL_SIOCTL_METHOD_OUT_DIRECT: + + // + // In this type of transfer, the I/O manager allocates a system buffer + // large enough to accommodate the User input buffer, sets the buffer address + // in Irp->AssociatedIrp.SystemBuffer and copies the content of user input buffer + // into the SystemBuffer. For the output buffer, the I/O manager + // probes to see whether the virtual address is writable in the callers + // access mode, locks the pages in memory and passes the pointer to MDL + // describing the buffer in Irp->MdlAddress. + // + + + SIOCTL_KDPRINT(("Called IOCTL_SIOCTL_METHOD_OUT_DIRECT\n")); + + PrintIrpInfo(Irp); + + + inBuf = Irp->AssociatedIrp.SystemBuffer; + + SIOCTL_KDPRINT(("\tData from User : ")); + PrintChars(inBuf, inBufLength); + + // + // To access the output buffer, just get the system address + // for the buffer. For this method, this buffer is intended for transfering data + // from the driver to the application. + // + + buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); + + if (!buffer) { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + // + // Write data to be sent to the user in this buffer + // + + RtlCopyBytes(buffer, data, outBufLength); + + SIOCTL_KDPRINT(("\tData to User : ")); + PrintChars(buffer, datalen); + + Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen); + + // + // NOTE: Changes made to the SystemBuffer are not copied + // to the user input buffer by the I/O manager + // + + break; + + default: + + // + // The specified I/O control code is unrecognized by this driver. + // + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + SIOCTL_KDPRINT(("ERROR: unrecognized IOCTL %x\n", + irpSp->Parameters.DeviceIoControl.IoControlCode)); + break; + } + +End: + // + // Finish the I/O operation by simply completing the packet and returning + // the same status as in the packet itself. + // + + Irp->IoStatus.Status = ntStatus; + + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + + return ntStatus; +} + +VOID +PrintIrpInfo( + PIRP Irp) +{ + PIO_STACK_LOCATION irpSp; + irpSp = IoGetCurrentIrpStackLocation( Irp ); + + PAGED_CODE(); + + SIOCTL_KDPRINT(("\tIrp->AssociatedIrp.SystemBuffer = 0x%p\n", + Irp->AssociatedIrp.SystemBuffer)); + SIOCTL_KDPRINT(("\tIrp->UserBuffer = 0x%p\n", Irp->UserBuffer)); + SIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.Type3InputBuffer = 0x%p\n", + irpSp->Parameters.DeviceIoControl.Type3InputBuffer)); + SIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.InputBufferLength = %d\n", + irpSp->Parameters.DeviceIoControl.InputBufferLength)); + SIOCTL_KDPRINT(("\tirpSp->Parameters.DeviceIoControl.OutputBufferLength = %d\n", + irpSp->Parameters.DeviceIoControl.OutputBufferLength )); + return; +} + +VOID +PrintChars( + _In_reads_(CountChars) PCHAR BufferAddress, + _In_ size_t CountChars + ) +{ + PAGED_CODE(); + + if (CountChars) { + + while (CountChars--) { + + if (*BufferAddress > 31 + && *BufferAddress != 127) { + + KdPrint (( "%c", *BufferAddress) ); + + } else { + + KdPrint(( ".") ); + + } + BufferAddress++; + } + KdPrint (("\n")); + } + return; +} + + diff --git a/general/ioctl/wdm/sys/sioctl.h b/general/ioctl/wdm/sys/sioctl.h new file mode 100644 index 00000000..33c0ff4b --- /dev/null +++ b/general/ioctl/wdm/sys/sioctl.h @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) 1997 Microsoft Corporation + +Module Name: + + SIOCTL.H + +Abstract: + + + Defines the IOCTL codes that will be used by this driver. The IOCTL code + contains a command identifier, plus other information about the device, + the type of access with which the file must have been opened, + and the type of buffering. + +Environment: + + Kernel mode only. + +--*/ + +// +// Device type -- in the "User Defined" range." +// +#define SIOCTL_TYPE 40000 +// +// The IOCTL function codes from 0x800 to 0xFFF are for customer use. +// +#define IOCTL_SIOCTL_METHOD_IN_DIRECT \ + CTL_CODE( SIOCTL_TYPE, 0x900, METHOD_IN_DIRECT, FILE_ANY_ACCESS ) + +#define IOCTL_SIOCTL_METHOD_OUT_DIRECT \ + CTL_CODE( SIOCTL_TYPE, 0x901, METHOD_OUT_DIRECT , FILE_ANY_ACCESS ) + +#define IOCTL_SIOCTL_METHOD_BUFFERED \ + CTL_CODE( SIOCTL_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS ) + +#define IOCTL_SIOCTL_METHOD_NEITHER \ + CTL_CODE( SIOCTL_TYPE, 0x903, METHOD_NEITHER , FILE_ANY_ACCESS ) + + +#define DRIVER_FUNC_INSTALL 0x01 +#define DRIVER_FUNC_REMOVE 0x02 + +#define DRIVER_NAME "SIoctl" + diff --git a/general/ioctl/wdm/sys/sioctl.rc b/general/ioctl/wdm/sys/sioctl.rc new file mode 100644 index 00000000..a93374ac --- /dev/null +++ b/general/ioctl/wdm/sys/sioctl.rc @@ -0,0 +1,10 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "Sample IOCTL Driver" +#define VER_INTERNALNAME_STR "SIOCTL.sys" + +#include "common.ver" diff --git a/general/ioctl/wdm/sys/sioctl.vcxproj b/general/ioctl/wdm/sys/sioctl.vcxproj new file mode 100644 index 00000000..7340c780 --- /dev/null +++ b/general/ioctl/wdm/sys/sioctl.vcxproj @@ -0,0 +1,140 @@ +<?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>{EFC79CFC-9D17-4830-90C1-1825B6CFE1AD}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{733A9BE6-EB74-47AD-9701-2DB93FD4B2AC}</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>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType>WDM</DriverType> + <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset> + <ConfigurationType>Driver</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" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>sioctl</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>sioctl</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>sioctl</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>sioctl</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <TreatWarningAsError>true</TreatWarningAsError> + <WarningLevel>Level4</WarningLevel> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="sioctl.c" /> + <ResourceCompile Include="sioctl.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/general/ioctl/wdm/sys/sioctl.vcxproj.Filters b/general/ioctl/wdm/sys/sioctl.vcxproj.Filters new file mode 100644 index 00000000..3b5a4633 --- /dev/null +++ b/general/ioctl/wdm/sys/sioctl.vcxproj.Filters @@ -0,0 +1,31 @@ +<?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>{68FEC55D-22E4-4CC8-86A7-C923C2AB8F07}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{9D595192-13EA-4968-AFE4-63BECD7EDD64}</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>{644100AF-059B-48EE-B8B9-280BA8724FF6}</UniqueIdentifier> + </Filter> + <Filter Include="Driver Files"> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + <UniqueIdentifier>{41B8EECC-BA42-433E-9150-6D2D385CC021}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="sioctl.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="sioctl.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project>
\ No newline at end of file |
