从 C++ 调用 WDF 驱动程序

Calling WDF driver from c++

我一直在尝试调用示例驱动程序。我已经编写了 DriverEntry 方法,我在其中初始化驱动程序名称和指向驱动程序的符号 ling。

// UNICODE_STRING DriverName, SymbolName; // Driver registry paths
...
    // Driver Entrypoint
    NTSTATUS
    DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) {
  Q_UNUSED(pRegistryPath);

  DbgPrintEx(0, 0, "Driver Loaded\n");

  // The PsSetLoadImageNotifyRoutine routine registers a driver-supplied
  // callback that is subsequently notified whenever
  // an image is loaded (or mapped into memory).
  PsSetLoadImageNotifyRoutine(ImageLoadCallback);

  // initialize driver name
  RtlInitUnicodeString(&DriverName, L"\Device\Explorer");
  // initialize symbolic link
  RtlInitUnicodeString(&SymbolName, L"\DosDevices\Explorer");

  IoCreateDevice(pDriverObject, 0, &SymbolName, FILE_DEVICE_UNKNOWN,
                 FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
  IoCreateSymbolicLink(&DriverName, &SymbolName);

  pDriverObject->MajorFunction[IRP_MJ_CREATE] = CreateCall;
  pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseCall;
  pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;
  pDriverObject->DriverUnload = UnloadDriver;

  pDeviceObject->Flags |= DO_DIRECT_IO;
  pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

  return STATUS_SUCCESS;
}

当我加载驱动程序时(使用 OSR Driver Loader,也可以使用 cmd 完成,通过将驱动程序注册为新服务​​),我在 DebugView 中得到预期的输出(允许查看内核调试日志的 sysinternals 工具)

现在我需要确保设备和 symlink 都存在于 Windows 对象目录中。为此,我使用 WinObj(sysinternals 的另一个工具),这是输出

这里让我感到困惑的是,符号 link 位于 Device 文件夹中,而不是 GLOBAL??。 设备中的符号 link

全球范围内的设备??

现在,终于可以调用驱动程序本身了。为此,我使用 C++,这是我的代码,

class Test
{
public:
HANDLE hDriver; // Handle to driver

                // Initializer
Test::Test(LPCSTR RegistryPath)
{
    LPCSTR path = "\\.\Explorer";
    hDriver = CreateFileA(path, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);


    if (hDriver == INVALID_HANDLE_VALUE)
    {
        //  Handle the error.
        char result = GetLastError();
        bool zadek = false;
    }
}

问题是我无法获得驱动程序的有效句柄。无论我使用什么路径,hDriver 的值始终是 0x00000000000000a0 或 0xffffffff。我正在使用 createFileA 因为我想访问系统内存。

我犯了一些明显的错误吗?

我应该说自从我上次编写设备驱动程序以来已有 8-9 年多了,但我的脑海中浮现的是:

  1. 你说你得到 0xa0 for hDriver 这是一个有效的句柄值。
  2. 目前,您只能使用设备IO控制,因为您只有IRP_MJ_DEVICE_CONTROL的回调。
  3. 尝试 L"\??\Explorer"L"\GLOBAL??\Explorer" 符号 link。
  4. 您需要为 IoCreateDevice 使用 DriverName
  5. 您向 IoCreateSymbolicLink 传递了不正确的参数。

所以你的代码应该变成这样:

...
// initialize driver name
RtlInitUnicodeString(&DriverName, L"\Device\Explorer");
// initialize symbolic link
RtlInitUnicodeString(&SymbolName, L"\??\Explorer");

IoCreateDevice(pDriverObject, 0, &DriverName, FILE_DEVICE_UNKNOWN,
                 FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
IoCreateSymbolicLink(&SymbolName, &DriverName);
...