310 lines
6.1 KiB
C
310 lines
6.1 KiB
C
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT AUTHORS, 2016 - 2017
|
|
*
|
|
* TITLE: MAIN.C
|
|
*
|
|
* VERSION: 1.01
|
|
*
|
|
* DATE: 20 Apr 2017
|
|
*
|
|
* "Driverless" example #2
|
|
*
|
|
* 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.
|
|
*
|
|
*******************************************************************************/
|
|
#include <ntddk.h>
|
|
#include "main.h"
|
|
|
|
#define DEBUGPRINT
|
|
|
|
/*
|
|
* PrintIrql
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Debug print current irql.
|
|
*
|
|
*/
|
|
VOID PrintIrql()
|
|
{
|
|
KIRQL Irql;
|
|
PWSTR sIrql;
|
|
|
|
Irql = KeGetCurrentIrql();
|
|
|
|
switch (Irql) {
|
|
|
|
case PASSIVE_LEVEL:
|
|
sIrql = L"PASSIVE_LEVEL";
|
|
break;
|
|
case APC_LEVEL:
|
|
sIrql = L"APC_LEVEL";
|
|
break;
|
|
case DISPATCH_LEVEL:
|
|
sIrql = L"DISPATCH_LEVEL";
|
|
break;
|
|
case CMCI_LEVEL:
|
|
sIrql = L"CMCI_LEVEL";
|
|
break;
|
|
case CLOCK_LEVEL:
|
|
sIrql = L"CLOCK_LEVEL";
|
|
break;
|
|
case IPI_LEVEL:
|
|
sIrql = L"IPI_LEVEL";
|
|
break;
|
|
case HIGH_LEVEL:
|
|
sIrql = L"HIGH_LEVEL";
|
|
break;
|
|
default:
|
|
sIrql = L"Unknown Value";
|
|
break;
|
|
}
|
|
DbgPrint("KeGetCurrentIrql=%u(%ws)\n", Irql, sIrql);
|
|
}
|
|
|
|
/*
|
|
* DevioctlDispatch
|
|
*
|
|
* Purpose:
|
|
*
|
|
* IRP_MJ_DEVICE_CONTROL dispatch.
|
|
*
|
|
*/
|
|
NTSTATUS DevioctlDispatch(
|
|
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
|
_Inout_ struct _IRP *Irp
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
ULONG bytesIO = 0;
|
|
PIO_STACK_LOCATION stack;
|
|
BOOLEAN condition = FALSE;
|
|
PINOUTPARAM rp, wp;
|
|
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s IRP_MJ_DEVICE_CONTROL", __FUNCTION__);
|
|
#endif
|
|
|
|
stack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
do {
|
|
|
|
if (stack == NULL) {
|
|
status = STATUS_INTERNAL_ERROR;
|
|
break;
|
|
}
|
|
|
|
rp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer;
|
|
wp = (PINOUTPARAM)Irp->AssociatedIrp.SystemBuffer;
|
|
if (rp == NULL) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
switch (stack->Parameters.DeviceIoControl.IoControlCode) {
|
|
case DUMMYDRV_REQUEST1:
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s DUMMYDRV_REQUEST1 hit", __FUNCTION__);
|
|
#endif
|
|
if (stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(INOUT_PARAM)) {
|
|
status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s in params = %lx, %lx, %lx, %lx", __FUNCTION__,
|
|
rp->Param1, rp->Param2, rp->Param3, rp->Param4);
|
|
#endif
|
|
|
|
wp->Param1 = 11111111;
|
|
wp->Param2 = 22222222;
|
|
wp->Param3 = 33333333;
|
|
wp->Param4 = 44444444;
|
|
|
|
status = STATUS_SUCCESS;
|
|
bytesIO = sizeof(INOUT_PARAM);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s hit with invalid IoControlCode", __FUNCTION__);
|
|
#endif
|
|
status = STATUS_INVALID_PARAMETER;
|
|
};
|
|
|
|
} while (condition);
|
|
|
|
Irp->IoStatus.Status = status;
|
|
Irp->IoStatus.Information = bytesIO;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* UnsupportedDispatch
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Unused IRP_MJ_* dispatch.
|
|
*
|
|
*/
|
|
NTSTATUS UnsupportedDispatch(
|
|
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
|
_Inout_ struct _IRP *Irp
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return Irp->IoStatus.Status;
|
|
}
|
|
|
|
/*
|
|
* CreateDispatch
|
|
*
|
|
* Purpose:
|
|
*
|
|
* IRP_MJ_CREATE dispatch.
|
|
*
|
|
*/
|
|
NTSTATUS CreateDispatch(
|
|
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
|
_Inout_ struct _IRP *Irp
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s Create", __FUNCTION__);
|
|
#endif
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return Irp->IoStatus.Status;
|
|
}
|
|
|
|
/*
|
|
* CloseDispatch
|
|
*
|
|
* Purpose:
|
|
*
|
|
* IRP_MJ_CLOSE dispatch.
|
|
*
|
|
*/
|
|
NTSTATUS CloseDispatch(
|
|
_In_ struct _DEVICE_OBJECT *DeviceObject,
|
|
_Inout_ struct _IRP *Irp
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s Close", __FUNCTION__);
|
|
#endif
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return Irp->IoStatus.Status;
|
|
}
|
|
|
|
/*
|
|
* DriverInitialize
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Driver main.
|
|
*
|
|
*/
|
|
NTSTATUS DriverInitialize(
|
|
_In_ struct _DRIVER_OBJECT *DriverObject,
|
|
_In_ PUNICODE_STRING RegistryPath
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
UNICODE_STRING SymLink, DevName;
|
|
PDEVICE_OBJECT devobj;
|
|
ULONG t;
|
|
|
|
//RegistryPath is NULL
|
|
UNREFERENCED_PARAMETER(RegistryPath);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s\n", __FUNCTION__);
|
|
#endif
|
|
|
|
RtlInitUnicodeString(&DevName, L"\\Device\\TDLD");
|
|
status = IoCreateDevice(DriverObject, 0, &DevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, &devobj);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s IoCreateDevice(%wZ) = %lx\n", __FUNCTION__, DevName, status);
|
|
#endif
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
RtlInitUnicodeString(&SymLink, L"\\DosDevices\\TDLD");
|
|
status = IoCreateSymbolicLink(&SymLink, &DevName);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s IoCreateSymbolicLink(%wZ) = %lx\n", __FUNCTION__, SymLink, status);
|
|
#endif
|
|
|
|
devobj->Flags |= DO_BUFFERED_IO;
|
|
|
|
for (t = 0; t <= IRP_MJ_MAXIMUM_FUNCTION; t++)
|
|
DriverObject->MajorFunction[t] = &UnsupportedDispatch;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &DevioctlDispatch;
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = &CreateDispatch;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = &CloseDispatch;
|
|
DriverObject->DriverUnload = NULL; //nonstandard way of driver loading, no unload
|
|
|
|
devobj->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* DriverEntry
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Driver base entry point.
|
|
*
|
|
*/
|
|
NTSTATUS DriverEntry(
|
|
_In_ struct _DRIVER_OBJECT *DriverObject,
|
|
_In_ PUNICODE_STRING RegistryPath
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
UNICODE_STRING drvName;
|
|
|
|
/* This parameters are invalid due to nonstandard way of loading and should not be used. */
|
|
UNREFERENCED_PARAMETER(DriverObject);
|
|
UNREFERENCED_PARAMETER(RegistryPath);
|
|
|
|
PrintIrql();
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s\n", __FUNCTION__);
|
|
#endif
|
|
|
|
RtlInitUnicodeString(&drvName, L"\\Driver\\TDLD");
|
|
status = IoCreateDriver(&drvName, &DriverInitialize);
|
|
|
|
#ifdef DEBUGPRINT
|
|
DbgPrint("%s IoCreateDriver(%wZ) = %lx\n", __FUNCTION__, drvName, status);
|
|
#endif
|
|
|
|
return status;
|
|
}
|