Can't Unload "Hello World" KMDF Driver

Here is my code which I got from Microsoft "Hello World" KMDF webpage:

#include <ntddk.h>
#include <wdf.h>

DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_DEVICE_ADD KmdfHelloWorldEvtDeviceAdd;
DRIVER_UNLOAD DriverUnload;

// This is my custom declared function
VOID KernelModeFunction(VOID);

// Callback function implementation
VOID MyLoadImageNotifyRoutine(
In_opt PUNICODE_STRING FullImageName,
In HANDLE ProcessId,
In PIMAGE_INFO ImageInfo
)
{
// Process the image load notification.
// Access the image name (FullImageName), process ID (ProcessId), and image information (ImageInfo).
UNREFERENCED_PARAMETER(ImageInfo);

if (FullImageName != NULL) {
    // Handle the image load event.
    // For example, log the image name and process ID.
    DbgPrint("KernelProt: Image loaded: %wZ, Process ID: %d\n", FullImageName, ProcessId);
    DbgPrint("Address of KernelModeFunction is %x\n", KernelModeFunction);
}

}

NTSTATUS
DriverEntry
(
In PDRIVER_OBJECT DriverObject,
In PUNICODE_STRING RegistryPath
)
{
// NTSTATUS variable to record success or failure
NTSTATUS status = STATUS_SUCCESS;

// Allocate the driver configuration object
WDF_DRIVER_CONFIG config;

// Print "Hello World" for DriverEntry
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n"));

// Initialize the driver configuration object to register the
// entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd

WDF_DRIVER_CONFIG_INIT(&config,
    KmdfHelloWorldEvtDeviceAdd
);

// Finally, create the driver object
status = WdfDriverCreate(DriverObject,
    RegistryPath,
    WDF_NO_OBJECT_ATTRIBUTES,
    &config,
    WDF_NO_HANDLE
);

// register our MyLoadImageNotifyRoutine
status = PsSetLoadImageNotifyRoutine(MyLoadImageNotifyRoutine);

// register our driver unload function
DriverObject->DriverUnload = DriverUnload;

return status;

}

NTSTATUS
KmdfHelloWorldEvtDeviceAdd(
In WDFDRIVER Driver,
Inout PWDFDEVICE_INIT DeviceInit
)
{
// We're not using the driver object,
// so we need to mark it as unreferenced
UNREFERENCED_PARAMETER(Driver);

NTSTATUS status;

// Allocate the device object
WDFDEVICE hDevice;

// Print "Hello World"
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n"));

// Create the device object
status = WdfDeviceCreate(&DeviceInit,
    WDF_NO_OBJECT_ATTRIBUTES,
    &hDevice
);
return status;

}

void DriverUnload
(
In PDRIVER_OBJECT DriverObject
)
{
UNREFERENCED_PARAMETER(DriverObject);

// remove the registered callback function 
PsRemoveLoadImageNotifyRoutine(MyLoadImageNotifyRoutine);
KdPrint(("KernelProt DriverUnload has been called\r\n"));

}

VOID KernelModeFunction(VOID)
{

}

Here is the command line output for loading and unloading this driver.

c:\TestDir>sc.exe start kernelprotsvc

SERVICE_NAME: kernelprotsvc
TYPE : 1 KERNEL_DRIVER
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
PID : 0
FLAGS :

c:\TestDir>sc.exe stop kernelprotsvc
[SC] ControlService FAILED 1052:

The requested control is not valid for this service.

Just wanted to share a solution that I found right here on OSR for anyone having the same or similar problem. Read here Driver services - NTDEV - OSR Developer Community.

Hope it helps someone else.

This is a plug-and-play driver. You don't load and unload it with the "sc" tool. You have to enable or disable the underlying hardware device that triggers its loading.

Thanks Tim. When you say "You have to enable or disable the underlying hardware device...." Do mean to enable/disable it under device manager and second question by enable/disabling it will the overridden EvtWdfDriverUnload or DriverUnload routine be called ?

You should just register an EvtDriverUnload callback function and remove DriverObject->DriverUnload = DriverUnload;

Thanks Mark. I'll make that change. I really appreciate the help.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.