ThinkNotes

Simple is not easy | 化繁为简,知易行难

0%

WDF PCIe-SD Host Controller Driver Analysis

Windows WDF PCIe-SD Host Controller Driver Analysis

Current Status Analysis

Based on the dumpfile information:

1. Driver Stack Structure - Correct

  • Device stack is properly established: partmgr → disk → sdhcstor

  • Upper layer device (disk.sys) successfully starts and attaches to your driver

  • ServiceName is “disk”, DeviceInst shows correct device path

2. Critical Issue: ExtensionFlags Inconsistency

Device object ffffc701663ddc80 (Upper device):

  • ⚠️ ExtensionFlags = 0x0000000000 (Highlighted in orange - THIS IS THE PROBLEM)

  • This device object is missing necessary extension flags

Device object ffffc70162a1aa0 (Driver object):

  • ✓ ExtensionFlags = 0x00000800 (DOE_DEFAULT_SD_PRESENT)

  • This flag indicates SD card present - this is correct

3. BSOD Root Cause Analysis

ExtensionFlags being 0 indicates:

  • Device extension object may not be properly initialized

  • I/O buffer management related extension information is missing

  • Likely missing proper setup during IRP_MJ_CREATE or device creation

Solution Correctness Assessment

✓ Correct Aspects:

  1. I/O Queue Implementation - Sequential handling of Read/Write requests is correct

  2. Driver Stack Architecture - Functioning as port driver below disk.sys is standard architecture

  3. Device Attachment - Upper device successfully attaching indicates AddDevice is fundamentally correct

Areas Requiring Correction:

  1. Device Extension Object Initialization
1
2
3
// Check your EvtDeviceAdd or device creation code
// Ensure proper Device Extension setup
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
  1. ExtensionFlags Configuration
  • Verify proper call to WdfDeviceInitSetDeviceType()

  • Ensure device characteristics flags are correctly set:

  • FILE_AUTOGENERATED_DEVICE_NAME

  • FILE_DEVICE_SECURE_OPEN

  • FILE_PORTABLE_DEVICE

  1. I/O Buffer Management Critical Points
1
2
3
4
5
// Set correct buffer method during device initialization
WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect); // or WdfDeviceIoBuffered

// Ensure proper alignment requirements are set
WdfDeviceInitSetIoInCallerContextCallback(DeviceInit, YourPreprocessCallback);
  1. Verify Device Extension Allocation
  • Confirm DEVICE_CONTEXT structure is properly allocated and initialized

  • Use !wdfkd.wdfdevice command to inspect WDF device object state

  1. Add Tracing
1
2
3
4
5
// Add DbgPrint or WPP tracing at critical points:
- EvtDeviceAdd
- EvtDevicePrepareHardware
- I/O Queue callbacks
- Buffer mapping/locking operations
  1. Validate DMA/Buffer Operations
  • Check if DMA Enabler is properly created (if using DMA)

  • Verify MDL (Memory Descriptor List) handling

  • Ensure all buffer pointers are properly locked and mapped before use

  1. Inspect IRP Handling
1
2
3
4
// Ensure proper handling of these IRPs during mount:
- IRP_MJ_CREATE
- IRP_MJ_DEVICE_CONTROL (IOCTL_MOUNTDEV_*)
- IRP_MJ_PNP (especially IRP_MN_QUERY_CAPABILITIES)

Specific Code Areas to Review

Device Initialization (Priority #1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
NTSTATUS
YourEvtDeviceAdd(
WDFDRIVER Driver,
PWDFDEVICE_INIT DeviceInit
)
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
WDFDEVICE device;
NTSTATUS status;

// CRITICAL: Set device type
WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_MASS_STORAGE);

// CRITICAL: Set I/O type
WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);

// CRITICAL: Set device characteristics
WdfDeviceInitSetCharacteristics(DeviceInit,
FILE_AUTOGENERATED_DEVICE_NAME |
FILE_DEVICE_SECURE_OPEN |
FILE_PORTABLE_DEVICE,
FALSE);

// Initialize device context
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);

status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
if (!NT_SUCCESS(status)) {
return status;
}

// Initialize device extension here
PDEVICE_CONTEXT context = GetDeviceContext(device);
// Ensure all fields are properly initialized

return status;
}

Buffer Handling in I/O Queue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
VOID
YourEvtIoRead(
WDFQUEUE Queue,
WDFREQUEST Request,
size_t Length
)
{
NTSTATUS status;
WDFMEMORY memory;
PVOID buffer;

// CRITICAL: Proper buffer retrieval
status = WdfRequestRetrieveOutputMemory(Request, &memory);
if (!NT_SUCCESS(status)) {
WdfRequestComplete(Request, status);
return;
}

buffer = WdfMemoryGetBuffer(memory, NULL);
if (buffer == NULL) {
WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
return;
}

// Ensure buffer is locked/mapped before hardware access
// Your DMA or PIO operation here
}

Next Steps

  1. Immediate Action: Review Device Extension initialization code, ensure all necessary flags are set during device creation

  2. Set Breakpoints: On all I/O request handlers before mount operation

  3. Verify: WdfDeviceInitSetDeviceType() and related device characteristics configuration

  4. Analyze: Specific bugcheck code and parameters from the BSOD (if complete minidump available)

Conclusion

Overall Assessment: Your architecture is fundamentally correct. The issue is concentrated in device object initialization and extension flags configuration. This is a typical detail that’s easy to overlook in WDF driver development, but critical for proper I/O buffer management.

The fact that:

  • Device stack builds correctly

  • Upper device attaches successfully

  • Queue shows “not busy”

…indicates the framework is mostly correct. The ExtensionFlags discrepancy is the smoking gun pointing to incomplete device initialization during the AddDevice routine.

Confidence Level: High - This is a common pattern in WDF driver issues related to mount failures and I/O buffer management.

Would you like me to review your source code to provide more specific corrections?