microsoft / windows-drivers-rs

Platform that enables Windows driver development in Rust. Developed by Surface.
Apache License 2.0
1.5k stars 66 forks source link

Windows 10 `wdk-sys` Driver Compilation and Loading Error #42

Open ghost opened 11 months ago

ghost commented 11 months ago

Hello friend,

I've noticed that a lot of people, especially in various Discord communities, are discussing an issue with the Windows 10 driver not working correctly for wdk-sys. Here's a step-by-step outline of the problem:

Steps to Reproduce:

  1. Start with a Windows 10 environment.
  2. Attempt to compile the Hello World Driver.
  3. Load the driver using the following commands:
    sc.exe create test type= kernel binPath= C:\Windows\System32\drivers\test.sys
    sc.exe query test
    sc.exe start test

Observed Issue: On executing the above steps, the following error messages are observed:

[SC] CreateService FAILED 1073:

The specified service already exists.

SERVICE_NAME: test
        TYPE               : 1  KERNEL_DRIVER 
        STATE              : 1  STOPPED 
        WIN32_EXIT_CODE    : 87  (0x57)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
[SC] StartService FAILED 87:

The parameter is incorrect.

Additional Notes:

I'd appreciate any insights or solutions to resolve this issue on Windows 10.

Thank you!

wmmc88 commented 11 months ago

Hi @Juggle4247. Are you able to reproduce this issue when following the instructions at https://github.com/microsoft/windows-drivers-rs/tree/main/crates/sample-kmdf-driver#sample-kmdf-rust-driver ? One possible reason for this is that the current signing flow in rust-driver-makefile.toml only signs the catalog file. By bypassing PnP installation, I believe you end up being in violation of the kernel-mode code signing policy.

ghost commented 11 months ago

Hello, I do not understand what you mean. Did you test this on Microsoft Windows 10? Can you please upload kernel driver template that works both on Windows 10 and 11? This would be great and lot easier for other people.

Celestialme commented 10 months ago

I have the same issue, I also could not run it without signing both cat and sys files, but now it says The parameter is incorrect.

not-matthias commented 9 months ago

Using the following build.rs fixed it for me:

fn main() -> Result<(), wdk_build::ConfigError> {
    let mut config = wdk_build::Config::from_env_auto()?;
    config.driver_config = wdk_build::DriverConfig::WDM();
    config.configure_binary_build();
    Ok(())
}

(Code taken from here: https://github.com/microsoft/windows-drivers-rs/discussions/32)

wmmc88 commented 9 months ago

Got some bandwidth to do some more debugging of this issue and was able to figure it out. @not-matthias 's workaround only works if you are fine using only non-WDF functions. it limits you to what's only available in WDM drivers. The reason it works is because it changes the linker flags to set the entry point to be DriverEntry, instead of FxDriverEntry, so WDF doesn't get called into at all.

WDF initialization is causing issues for you folks on W10 because various things in the default config of this crate (as currently available in v0.1.0 in crates.io) default to kmdf V1.33 which only supports W11 21H2 and newer. I've verified that when setting all references to v1.31 results in a correctly functioning sample_kmdf_driver and echo_2. These are the changes I had to make:

diff --git a/crates/wdk-build/src/lib.rs b/crates/wdk-build/src/lib.rs
index 55b002d..cf08422 100644
--- a/crates/wdk-build/src/lib.rs
+++ b/crates/wdk-build/src/lib.rs
@@ -624,7 +624,7 @@ fn default() -> Self {
         // FIXME: determine default values from TargetVersion and _NT_TARGET_VERSION
         Self {
             kmdf_version_major: 1,
-            kmdf_version_minor: 33,
+            kmdf_version_minor: 31,
         }
     }
 }
 diff --git a/crates/wdk-sys/src/lib.rs b/crates/wdk-sys/src/lib.rs
index 01ed616..891c8fb 100644
--- a/crates/wdk-sys/src/lib.rs
+++ b/crates/wdk-sys/src/lib.rs
@@ -59,16 +59,16 @@ pub extern "system" fn __CxxFrameHandler3() -> i32 {
 lazy_static! {
     #[allow(missing_docs)]
     pub static ref WDF_FUNCTION_TABLE: &'static [WDFFUNC] = {
-        // SAFETY: `WdfFunctions_01033` is generated as a mutable static, but is not supposed to be ever mutated by WDF.
-        let wdf_function_table = unsafe { WdfFunctions_01033 };
+        // SAFETY: `WdfFunctions_01031` is generated as a mutable static, but is not supposed to be ever mutated by WDF.
+        let wdf_function_table = unsafe { WdfFunctions_01031 };

         // SAFETY: `WdfFunctionCount` is generated as a mutable static, but is not supposed to be ever mutated by WDF.
         let wdf_function_count = unsafe { WdfFunctionCount } as usize;

         // SAFETY: This is safe because:
-        //         1. `WdfFunctions_01033` is valid for reads for `WdfFunctionCount` * `core::mem::size_of::<WDFFUNC>()`
+        //         1. `WdfFunctions_01031` is valid for reads for `WdfFunctionCount` * `core::mem::size_of::<WDFFUNC>()`
         //            bytes, and is guaranteed to be aligned and it must be properly aligned.
-        //         2. `WdfFunctions_01033` points to `WdfFunctionCount` consecutive properly initialized values of
+        //         2. `WdfFunctions_01031` points to `WdfFunctionCount` consecutive properly initialized values of
         //            type `WDFFUNC`.
         //         3. WDF does not mutate the memory referenced by the returned slice for for its entire `'static' lifetime.
         //         4. The total size, `WdfFunctionCount` * `core::mem::size_of::<WDFFUNC>()`, of the slice must be no
diff --git a/crates/wdk-sys/src/wdf.rs b/crates/wdk-sys/src/wdf.rs
index 2a6615a..20eb364 100644
--- a/crates/wdk-sys/src/wdf.rs
+++ b/crates/wdk-sys/src/wdf.rs
@@ -20,4 +20,4 @@ mod bindings {
 // FIXME: UMDF >= 2.25 & KMDF >= 1.25 define this in wdffuncenum with
 // _declspec(selectany) so they don't generate symbols
 #[no_mangle]
-static WdfMinimumVersionRequired: ULONG = 33;
+static WdfMinimumVersionRequired: ULONG = 31;
diff --git a/rust-driver-makefile.toml b/rust-driver-makefile.toml
index 29deaf6..6e11734 100644

Unfortunately, these source patches are required to compile a driver for W10 right now, but should no longer be required once #82 (which is currently my main focus) is addressed.