mirror of
https://github.com/zer0condition/GoodmansKernel/
synced 2026-08-19 01:14:35 +00:00
122 lines
4.0 KiB
C
122 lines
4.0 KiB
C
/* driver.c - entry, device create, dispatch */
|
|
#include "inc/gvm.h"
|
|
#include "../shared/goodmans_ioctl.h"
|
|
|
|
DRIVER_INITIALIZE DriverEntry;
|
|
static DRIVER_UNLOAD gvm_unload;
|
|
static DRIVER_DISPATCH gvm_create_close;
|
|
static DRIVER_DISPATCH gvm_device_control;
|
|
|
|
PDEVICE_OBJECT g_device;
|
|
static UNICODE_STRING g_symlink;
|
|
|
|
NTSTATUS
|
|
DriverEntry(_In_ PDRIVER_OBJECT drv, _In_ PUNICODE_STRING regpath)
|
|
{
|
|
UNREFERENCED_PARAMETER(regpath);
|
|
|
|
// filter mask so DbgView captures our lines without Verbose
|
|
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, TRUE);
|
|
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_WARNING_LEVEL, TRUE);
|
|
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, TRUE);
|
|
DbgSetDebugFilterState(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, TRUE);
|
|
|
|
gvm_log_init();
|
|
gvm_trace_init();
|
|
gvm_watchdog_start();
|
|
gvm_log("driver load");
|
|
|
|
UNICODE_STRING dev_name;
|
|
RtlInitUnicodeString(&dev_name, GVM_DEVICE_NAME_U);
|
|
|
|
NTSTATUS s = IoCreateDevice(drv, 0, &dev_name, GVM_DEVICE_TYPE,
|
|
FILE_DEVICE_SECURE_OPEN, FALSE, &g_device);
|
|
if (!NT_SUCCESS(s)) {
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[goodmans] IoCreateDevice=%08x\n", s);
|
|
return s;
|
|
}
|
|
|
|
RtlInitUnicodeString(&g_symlink, GVM_SYMLINK_NAME_U);
|
|
s = IoCreateSymbolicLink(&g_symlink, &dev_name);
|
|
if (!NT_SUCCESS(s)) {
|
|
IoDeleteDevice(g_device);
|
|
g_device = NULL;
|
|
return s;
|
|
}
|
|
|
|
s = gvm_modtab_init();
|
|
if (!NT_SUCCESS(s)) {
|
|
IoDeleteSymbolicLink(&g_symlink);
|
|
IoDeleteDevice(g_device);
|
|
g_device = NULL;
|
|
return s;
|
|
}
|
|
|
|
drv->MajorFunction[IRP_MJ_CREATE] = gvm_create_close;
|
|
drv->MajorFunction[IRP_MJ_CLOSE] = gvm_create_close;
|
|
drv->MajorFunction[IRP_MJ_DEVICE_CONTROL] = gvm_device_control;
|
|
drv->DriverUnload = gvm_unload;
|
|
|
|
g_device->Flags |= DO_BUFFERED_IO;
|
|
g_device->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
|
|
gvm_log("driver ready, device \\\\.\\Goodmans");
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
static VOID
|
|
gvm_unload(_In_ PDRIVER_OBJECT drv)
|
|
{
|
|
UNREFERENCED_PARAMETER(drv);
|
|
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[goodmans] unload\n");
|
|
|
|
gvm_ih_teardown();
|
|
gvm_watchdog_stop();
|
|
gvm_notify_teardown();
|
|
gvm_modtab_teardown();
|
|
|
|
if (g_symlink.Buffer)
|
|
IoDeleteSymbolicLink(&g_symlink);
|
|
if (g_device)
|
|
IoDeleteDevice(g_device);
|
|
}
|
|
|
|
static NTSTATUS
|
|
gvm_create_close(_In_ PDEVICE_OBJECT dev, _Inout_ PIRP irp)
|
|
{
|
|
UNREFERENCED_PARAMETER(dev);
|
|
irp->IoStatus.Status = STATUS_SUCCESS;
|
|
irp->IoStatus.Information = 0;
|
|
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
static NTSTATUS
|
|
gvm_device_control(_In_ PDEVICE_OBJECT dev, _Inout_ PIRP irp)
|
|
{
|
|
UNREFERENCED_PARAMETER(dev);
|
|
|
|
PIO_STACK_LOCATION sp = IoGetCurrentIrpStackLocation(irp);
|
|
NTSTATUS s = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
switch (sp->Parameters.DeviceIoControl.IoControlCode) {
|
|
case IOCTL_GVM_LOAD_MODULE: s = gvm_ioctl_load(irp, sp); break;
|
|
case IOCTL_GVM_CALL_EXPORT: s = gvm_ioctl_call(irp, sp); break;
|
|
case IOCTL_GVM_UNLOAD_MODULE: s = gvm_ioctl_unload(irp, sp); break;
|
|
case IOCTL_GVM_LIST_MODULES: s = gvm_ioctl_list(irp, sp); break;
|
|
case IOCTL_GVM_MODULE_INFO: s = gvm_ioctl_info(irp, sp); break;
|
|
case IOCTL_GVM_UNLOAD_ALL: s = gvm_ioctl_unload_all(irp, sp); break;
|
|
case IOCTL_GVM_TAIL_LOG: s = gvm_ioctl_tail_log(irp, sp); break;
|
|
case IOCTL_GVM_READ_GUEST: s = gvm_ioctl_read_guest(irp, sp); break;
|
|
case IOCTL_GVM_TAIL_TRACE: s = gvm_ioctl_tail_trace(irp, sp); break;
|
|
case IOCTL_GVM_TRACE_CTL: s = gvm_ioctl_trace_ctl(irp, sp); break;
|
|
case IOCTL_GVM_FORCE_UNLOAD: s = gvm_ioctl_force_unload(irp, sp); break;
|
|
case IOCTL_GVM_NOTIFY_STOP: s = gvm_ioctl_notify_stop(irp, sp); break;
|
|
default: break;
|
|
}
|
|
|
|
irp->IoStatus.Status = s;
|
|
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
|
return s;
|
|
}
|