从 C 语言的 Windows 内核驱动程序读取注册表

Jak*_*lis 3 c windows registry winapi kernel

我需要从注册表(最好)或文件中读取设置。该驱动程序是一个内核驱动程序,启动类型设置为SYSTEM,因此所有服务和 WinAPI 不一定可用。

我试图使用该RtlQueryRegistryValues函数从注册表中读取单个字符串值,但无论我做什么,我似乎都会得到相同的0xC0000034错误代码,并将其转换为STATUS_OBJECT_NAME_NOT_FOUND.

根据 MSDN 上提供的文档,当路径参数与有效密钥不匹配或设置了特定标志并且不满足该标志的特定条件时STATUS_OBJECT_NAME_NOT_FOUND返回。RtlQueryRegistryValues据我所知,注册表项实际上存在于我的测试机器中,并且我没有使用该RTL_QUERY_REGISTRY_REQUIRED标志。

我尝试读取的注册表值位于 下HKEY_LOCAL_MACHINE/SOFTWARE/company/ProjectName,我尝试读取默认值和名为 的 REG_SZ 值parameter。对的调用RtlQueryRegistryValues是在加载驱动程序的 DriverEntry(...) 阶段执行的。

我不知道我做错了什么,而且由于我是内核驱动程序的新手,而且调试过程非常繁琐,我不确定我是否只是错误地引用了注册表值,或者是否在系统启动的这个阶段,注册表完全可用。

mydriver.c

NTSTATUS DriverEntry(...) {
    NTSTATUS regStatus = 0;
    UNICODE_STRING data;
    RTL_QUERY_REGISTRY_TABLE query[2];
    WCHAR* regPath = L"\\Registry\\Machine\\SOFTWARE\\Company\\ProjectName";

    RtlZeroMemory(query, sizeof(RTL_QUERY_REGISTRY_TABLE) * 2);

    data.Buffer = NULL;
    data.MaximumLength = 0;
    data.Length = 0;

    // query[0].Name = L"Parameter";
    query[0].Name = L""; // L"" refers to the default value
    query[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
    query[0].EntryContext = &data;

    regStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, regPath, query, NULL, NULL);

    DebugPrint("regStatus: %lx\n", regStatus);
    DebugPrint("data: %wZ\n", &data);
}
Run Code Online (Sandbox Code Playgroud)

Igo*_*sky 7

我不是 100% 确定,但我怀疑软件子树的注册表配置单元尚未加载。你为什么还要尝试访问它?驱动程序配置参数的正确位置是其自己的注册表项 ( \Registry\Machine\System\CurrentControlSet\Services\<DriverName>\),并且它的路径甚至会传递给您的DriverEntry函数,因此您无需对其进行硬编码。

另请参阅:设备和驱动程序的注册表树和密钥