0

I try to open device object and send request to my driver by CreateFile and DeviceIoControl, but CreateFile fails with ERROR_INVALID_FUNCTION, also if I try to open device in WinObj - I get the same error, so how to solve this and what is it mean?

test_driver.c

#include "test_driver.h"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
    NTSTATUS status;
    PDEVICE_OBJECT deviceObject;
    UNICODE_STRING dNameString, dLinkString;

    RtlInitUnicodeString(&dNameString, NT_DEVICE_NAME);
    status = IoCreateDevice(DriverObject, sizeof(65533), &dNameString, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject);

    if (!NT_SUCCESS(status)) {
        return status;
    }

    RtlInitUnicodeString(&dLinkString, DOS_DEVICE_NAME);
    status = IoCreateSymbolicLink(&dLinkString, &dNameString);

    if (!NT_SUCCESS(status)) {
        IoDeleteDevice(deviceObject);
        return status;
    }

    DriverObject -> MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
    DriverObject -> DriverUnload = DriverUnload;

    DbgPrint("Driver loaded!");
    return STATUS_SUCCESS;
}

NTSTATUS DriverDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
    ULONG ioControlCode;
    PULONG ioBuffer;
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

    ioBuffer = Irp -> AssociatedIrp.SystemBuffer;
    ioControlCode = irpStack -> Parameters.DeviceIoControl.IoControlCode;
    Irp -> IoStatus.Status = STATUS_SUCCESS;
    Irp -> IoStatus.Information = 0;

    switch (ioControlCode) {
        case TEST_SMTH:
            ioBuffer[0] = (ULONG)DriverEntry;
            Irp -> IoStatus.Information = 4;
            break;

        default:
            Irp -> IoStatus.Status = STATUS_INVALID_PARAMETER;
            break;
    }

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("Request complete!");
    return Irp -> IoStatus.Status;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) {
    UNICODE_STRING dLinkString;

    RtlInitUnicodeString(&dLinkString, DOS_DEVICE_NAME);
    IoDeleteSymbolicLink(&dLinkString);
    IoDeleteDevice(DriverObject -> DeviceObject);
    DbgPrint("Driver unloaded!");
}

test_driver.h

#include <ntddk.h>

#define NT_DEVICE_NAME  L"\\Device\\testDrv" 
#define DOS_DEVICE_NAME L"\\DosDevices\\testDrv"

#define FIRST_IOCTL_INDEX 0x800
#define FILE_DEVICE_testDRV 0x00008000
#define TEST_SMTH CTL_CODE(FILE_DEVICE_testDRV, FIRST_IOCTL_INDEX + 101, METHOD_BUFFERED, FILE_ANY_ACCESS)

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NTSTATUS DriverDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);

From program source:

HANDLE device = CreateFile("\\\\.\\testDrv", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

I know that to open objects from NT space it is necessary to use NtCreateFile, but I created a symbolic link in my driver, so CreateFile must works well.

Andrii Matiiash
  • 499
  • 6
  • 18
  • Eerrr .. your error is in your test program but you haven't shared the code for that. What do you mean you created a *symbolic link* ? Do you mean a *weak symbol*? – Ahmed Masud Nov 04 '17 at 21:09
  • 1
    and what you want ? you not set `DriverObject -> MajorFunction[IRP_MJ_CREATE]`. default handler return `STATUS_INVALID_DEVICE_REQUEST` which converted to `ERROR_INVALID_FUNCTION` – RbMm Nov 04 '17 at 21:16
  • I didn`t know that it necessary, as i understood from some articles. I added IRP_MJ_CREATE and IRP_MJ_CLOSE functions and it works, thanks. I mean that I created link for device name by IoCreateSymbolicLink. – Andrii Matiiash Nov 04 '17 at 21:24
  • you need also `IRP_MJ_CLEANUP` have – RbMm Nov 04 '17 at 21:25
  • what sense use `sizeof(65533)` instead simply `4` ? – RbMm Nov 04 '17 at 21:30
  • also you not set `DeviceObject->Flags` as result you anyway can not open this device and you not got buffered io - `ioBuffer = Irp -> AssociatedIrp.SystemBuffer;` is error – RbMm Nov 04 '17 at 21:32
  • @AhmedMasud, NT applications and drivers have direct access to the root object namespace (e.g. "\Device", "\Sessions", "\RPC Control", "\Global??", "\BaseNamedObjects"), but Windows applications implicitly have a filtered view, e.g. devices are implicitly opened from links in the "\??" virtual directory (a combined view of "\Global??" and local logon-session links). Commonly they're called DOS device links (e.g. WinAPI `DefineDosDevice`) because classic DOS device names are linked here, such as drive letters and "COM1". But it's much more than just legacy device names. – Eryk Sun Nov 04 '17 at 22:14

1 Answers1

3

when somebody try open file on device DeviceObject, the DeviceObject->DriverObject->MajorFunction[IRP_MJ_CREATE] is called. now question - to where this point ? you not change this cell. you init only IRP_MJ_DEVICE_CONTROL cell. as result called default handler - IopInvalidDeviceRequest. this routine simply complete request with status STATUS_INVALID_DEVICE_REQUEST. win32 convert it to ERROR_INVALID_FUNCTION. so you and must got this error. if we want let open file on our device - need implement IRP_MJ_CREATE , IRP_MJ_CLEANUP and IRP_MJ_CLOSE how minimum

RbMm
  • 31,280
  • 3
  • 35
  • 56