You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual Studio 2022 KMDF驱动项目编译成功但未生成.sys文件

Visual Studio 2022 KMDF驱动项目编译成功但未生成.sys文件

我完全懂这种明明编译提示100%成功,却翻遍文件夹都找不到.sys文件的抓狂感——花了好几个小时排查却毫无头绪,太闹心了。结合你给出的环境、代码和已经做的排查步骤,我帮你梳理几个容易被忽略的关键点,应该能快速解决问题:

最常见的原因:找错了输出目录

很多人默认去项目根目录的Debug/Release文件夹找,但VS的驱动项目默认输出路径经常是解决方案目录下的x64\Debug(或Release)子文件夹,或者是带变量的路径(比如$(SolutionDir)$(Platform)\$(Configuration))。

  • 快速定位方法:
    1. 右键项目 → 属性 → 配置属性 → 常规,直接查看「输出目录」和「目标文件名」的具体路径;
    2. 或者在VS的「输出」窗口(编译时弹出的日志窗口)里翻最后几行,会有类似Copying file from "x64\Debug\ArgMuBridge.sys" to "C:\xxx\ArgMuBridge\x64\Debug\ArgMuBridge.sys"的日志,跟着路径直接找就行。

项目配置的隐藏开关被误改

虽然你用的是官方KMDF模板,但偶尔会有配置被意外改动的情况:

  • 右键项目 → 属性 → 配置属性 → 链接器 → 常规,确保「生成输出文件」是启用状态;
  • 再看「配置属性 → 驱动程序设置 → 常规」,确认「目标平台」是对应你的WDK版本的Windows 10,「驱动类型」是Kernel Mode Driver (KMDF),这两个没问题就继续。

尝试强制清理重新生成

有时候VS的中间文件缓存会搞鬼,明明编译成功却没生成最终文件:

  • 右键解决方案 → 重新生成解决方案,强制清理所有旧的中间文件和产物,再重新编译一次,大概率能解决缓存导致的问题。

权限问题(容易被忽略)

如果你的项目放在了C:\Windows、Program Files这类需要管理员权限的文件夹里,VS可能没有足够权限写入输出文件,导致文件生成失败但VS没报错:

  • 把项目移到用户目录下(比如C:\Users\Raphiel\source\repos\),或者用管理员身份启动VS再重新编译试试。

关于你代码里的警告

虽然C4312警告不影响编译通过,但还是建议规范一下:64位系统下HANDLE是8字节,ULONG是4字节,直接强制转换会有截断风险。后面补全读写逻辑时,把ProcessId转成HANDLE用系统提供的宏:

HANDLE hProcess = UlongToHandle(request->ProcessId);

附你提供的代码的格式化版本(修正了转义的头文件引用):

#include <ntifs.h>
#include <wdm.h>

// --- IOCTL DEFINITIONS ---
#define IOCTL_READ_PROCESS_MEMORY \
    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_WRITE_PROCESS_MEMORY \
    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

// --- DATA STRUCTURE ---
typedef struct _KERNEL_MEMORY_OPERATION {
    ULONG ProcessId;
    PVOID Address;
    PVOID pBuffer;
    ULONG Size;
} KERNEL_MEMORY_OPERATION, *PKERNEL_MEMORY_OPERATION;

// --- PROTOTYPES ---
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject);
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

// --- DRIVER ENTRY ---
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {
    UNREFERENCED_PARAMETER(RegistryPath);
    UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\ArgMuBridge");
    UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING(L"\\DosDevices\\ArgMuBridge");
    PDEVICE_OBJECT deviceObject = NULL;
    NTSTATUS status;

    status = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject);
    if (!NT_SUCCESS(status)) return status;

    status = IoCreateSymbolicLink(&symbolicLink, &deviceName);
    if (!NT_SUCCESS(status)) {
        IoDeleteDevice(deviceObject);
        return status;
    }

    DriverObject->DriverUnload = UnloadDriver;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;

    return STATUS_SUCCESS;
}

// --- UNLOAD ROUTINE ---
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject) {
    UNICODE_STRING symbolicLink = RTL_CONSTANT_STRING(L"\\DosDevices\\ArgMuBridge");
    IoDeleteSymbolicLink(&symbolicLink);
    IoDeleteDevice(DriverObject->DeviceObject);
}

// --- DISPATCH ROUTINES ---
NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
    UNREFERENCED_PARAMETER(DeviceObject);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
    UNREFERENCED_PARAMETER(DeviceObject);
    PIO_STACK_LOCATION stackLocation = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS status = STATUS_SUCCESS;
    PKERNEL_MEMORY_OPERATION request = (PKERNEL_MEMORY_OPERATION)Irp->AssociatedIrp.SystemBuffer;

    if (stackLocation) {
        switch (stackLocation->Parameters.DeviceIoControl.IoControlCode) {
            case IOCTL_READ_PROCESS_MEMORY: {
                // Logic omitted for simplicity
                break;
            }
            case IOCTL_WRITE_PROCESS_MEMORY: {
                // Logic omitted for simplicity
                break;
            }
            default:
                status = STATUS_INVALID_DEVICE_REQUEST;
                break;
        }
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:05:30