### INF DDInstall.CoInstallers Section Example Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/wdf/using-the-umdf-co-installer Demonstrates the structure of a DDInstall.CoInstallers section in an INF file, showing how it references AddReg and CopyFiles directives for co-installer setup. This section is crucial for the installation process of the co-installer. ```INF [MyDriver_Install.CoInstallers] AddReg = MyDriver_Install.CoInstallers_AddReg CopyFiles = MyDriver_CoInstallers_CopyFiles ``` -------------------------------- ### INF DDInstall Section Naming Examples Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-ddinstall-section Illustrates examples of DDInstall section names, including device-specific prefixes and platform extensions, as used in INF files for driver installation. ```INF [WDMPNPB003_Device] [GPR400.Install.NT] ``` -------------------------------- ### Install Windows Driver with DevCon Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/writing-your-first-driver Instructions for installing a test-signed Windows driver using the DevCon utility. It requires the driver's INF file and hardware ID. Examples show general syntax and specific commands, including handling path issues. ```Command Prompt devcon install ``` ```Command Prompt devcon install kmdfhelloworld.inf root\kmdfhelloworld ``` ```Command Prompt c:\tools\devcon install kmdfhelloworld.inf root\kmdfhelloworld ``` -------------------------------- ### Example: Set Device Setup Class GUID in WDF Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdfdeviceinitsetdeviceclass This code example demonstrates how to define a custom GUID and use WdfDeviceInitSetDeviceClass to set a device's setup class. This is typically done during device initialization to influence how the device is installed and its security settings. ```C++ DEFINE_GUID(GUID_DEVCLASS_MYUNIQUEID, 0xf149fe88, 0x f6cc, 0x47e3, 0x85, 0x94, 0xe2, 0xaa, 0xb6, 0xe0, 0x3b, 0xdf); WdfDeviceInitSetDeviceClass( DeviceInit, &GUID_DEVCLASS_MYUNIQUEID ); ``` -------------------------------- ### Install Windows Driver using DevCon Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/writing-a-very-small-kmdf--driver Instructions for installing a test-signed Windows driver using the `devcon install` command. This requires specifying the INF file and the hardware ID. Ensure the command prompt is run as Administrator. Provides examples for general syntax, a specific driver, and handling potential path issues for the DevCon tool. ```Batch devcon install ``` ```Batch devcon install kmdfhelloworld.inf root\kmdfhelloworld ``` ```Batch c:\tools\devcon install kmdfhelloworld.inf root\kmdfhelloworld ``` -------------------------------- ### WinDbg Debugger Commands Reference Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/debugger/getting-started-with-windbg--kernel-mode- A comprehensive reference of common WinDbg debugger commands, including standard commands, menu commands, and extension commands, for debugging Windows applications and drivers. ```APIDOC Command: Contents Source: Help menu Command: .sympath Description: Set symbol path Command: .reload Description: Reload module Command: x Description: Examine symbols Command: g Description: Go Command: dt Description: Display type Command: Break Source: Debug menu Command: lm Description: List loaded modules Command: k Description: Display stack backtrace (includes kb, kc, kd, kp, kp, kv variants) Command: bu Description: Set breakpoint (includes bp, bm variants) Command: bl Description: Breakpoint list Command: bc Description: Breakpoint clear Command: Step Into Source: Debug menu (F11) Command: !process Description: Display process information Command: !thread Description: Display thread information Command: !devnode Description: Display device node information Command: !devstack Description: Display device stack information Command: !drvobj Description: Display driver object information Command: qd Description: Quit and detach ``` -------------------------------- ### WinDbg Command-Line Options for Debugging Connections Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/debugger/performing-kernel-mode-debugging-using-windbg Examples demonstrating how to start WinDbg directly from the command line, specifying symbol paths and different kernel debugging connection types (COM port, network) with various parameters. ```Command Line windbg -y d:\mysymbols -k com:port=com2,baud=57600 ``` ```Command Line windbg -y d:\mysymbols -k com:port=\\.\com2,baud=115200 ``` ```Command Line windbg -y d:\mysymbols -k net:port=50000,key=AutoGeneratedKey ``` ```Command Line windbg -y d:\mysymbols -k net:port=50000,key=AutoGeneratedKey,target=TargetIPAddress ``` -------------------------------- ### List Loaded Modules in WinDbg Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/debugger/getting-started-with-windbg--kernel-mode- Use this command to display a list of all modules currently loaded by the target computer. The output includes information such as the start and end addresses of each module, its name, and symbol status. ```WinDbg Commands lm ``` ```WinDbg Output 0:000>3: kd> lm start end module name fffff800`00000000 fffff800`00088000 CI (deferred) ... fffff800`01143000 fffff800`01151000 BasicRender (deferred) fffff800`01151000 fffff800`01163000 BasicDisplay (deferred) ... fffff800`02a0e000 fffff800`03191000 nt (pdb symbols) C:\...\ntkrnlmp.pdb fffff800`03191000 fffff800`03200000 hal (deferred) ... ``` -------------------------------- ### Execute WinGet Configuration File for Driver Development Setup Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install-the-wdk-using-winget This command initiates the WinGet configuration process using the downloaded `configuration.dsc.yaml` file. It installs or updates all specified components, including Visual Studio, SDK, and WDK, to prepare the machine for driver development. Ensure the command is run from the directory containing the configuration file. ```Shell winget configure -f configuration.dsc.yaml ``` -------------------------------- ### Initialize Enterprise WDK Build Environment Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/download-the-wdk Detailed steps to set up the command-line build environment after downloading and mounting the EWDK ISO. This includes running the environment initialization script, configuring the Visual Studio environment, and launching the Visual Studio IDE from within the EWDK context. ```Batch LaunchBuildEnv.cmd SetupVSEnv "C:\Program Files\Microsoft Visual Studio\2022\%Community|Professional|Enterprise%\Common7\IDE\devenv.exe" ``` -------------------------------- ### Example: Create Duplex DMA Enabler and Get WDM Adapters Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdmaenabler/nf-wdfdmaenabler-wdfdmaenablerwdmgetdmaadapter This C++ example demonstrates how to initialize a WDF_DMA_ENABLER_CONFIG for a scatter-gather duplex DMA profile, create a WDF DMA enabler object, and then retrieve the underlying WDM DMA_ADAPTER structures for both read and write directions using WdfDmaEnablerWdmGetDmaAdapter. It includes basic error handling for the creation process. ```C++ NTSTATUS status = STATUS_SUCCESS; WDF_DMA_ENABLER_CONFIG dmaConfig; WDFDMAENABLER dmaEnabler; PDMA_ADAPTER readAdapter, writeAdapter; WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig, WdfDmaProfileScatterGatherDuplex, maxLength ); status = WdfDmaEnablerCreate( Device, &dmaConfig, WDF_NO_OBJECT_ATTRIBUTES, &dmaEnabler ); if (!NT_SUCCESS (status)) { return status; } readAdapter = WdfDmaEnablerWdmGetDmaAdapter( dmaEnabler, WdfDmaDirectionReadFromDevice ); writeAdapter = WdfDmaEnablerWdmGetDmaAdapter( dmaEnabler, WdfDmaDirectionWriteToDevice ); ``` -------------------------------- ### Search for Available Windows SDK and WDK Versions using WinGet Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install-the-wdk-using-winget These commands search the WinGet repository for all available versions of the Windows SDK and WDK, displaying a table of results including Name, ID, Version, and Source. ```Command Prompt winget search --source winget --id Microsoft.WindowsSDK ``` ```Command Prompt winget search --source winget --id Microsoft.WindowsWDK ``` -------------------------------- ### INF ClassGuid Entry Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-version-section Specifies the device setup class GUID. This GUID value identifies the device setup class to assign to devices, as well as the device class installer and any class-specific property page provider. This entry is required for device drivers installed through the PnP manager. ```APIDOC ClassGuid={nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn} GUID: string (hexadecimal digits) Description: Device setup class GUID. Purpose: - Assigns the device setup class to devices installed from this INF. - Identifies the device class installer and class-specific property page provider. Requirements: - For a new device setup class, a newly generated ClassGUID value is required. Notes: - Required for device drivers installed through the PnP manager. ``` -------------------------------- ### INF Example for Function and Filter Driver Installation Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-ddinstall-hw-section This INF file example demonstrates how a driver package can use the DDInstall.HW and DDInstall.Services sections to add both a function driver and a PnP upper filter driver. It includes AddReg directives for registry modifications and AddService directives for service installation, defining display names, service types, start types, error controls, and binary paths for both drivers. ```INF [Example_DDInstall] CopyFiles=example_copyfiles [Example_DDInstall.HW] AddReg=filter_addreg [filter_addreg] HKR,,"UpperFilters",0x00010000,"ExampleUpperFilter" ; [REG_MULTI_SZ](https://learn.microsoft.com/windows/desktop/SysInfo/registry-value-types) value [Example_DDInstall.Services] AddService=ExampleFunctionDriver,0x00000002,function_ServiceInstallSection AddService=ExampleUpperFilter,,filter_ServiceInstallSection [function_ServiceInstallSection] DisplayName = %function_ServiceDesc% ServiceType = 1 StartType = 3 ErrorControl = 1 ServiceBinary = %13%\ExampleFunctionDriver.sys [filter_ServiceInstallSection] DisplayName = %filter_ServiceDesc% ServiceType = 1 StartType = 3 ErrorControl = 1 ServiceBinary = %13%\ExampleUpperFilter.sys ``` -------------------------------- ### Initialize WDF_WMI_PROVIDER_CONFIG and Create WMI Provider Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfwmi/nf-wdfwmi-wdfwmiprovidercreate This C code example demonstrates how to initialize a WDF_WMI_PROVIDER_CONFIG structure with a GUID and flags, and then call WdfWmiProviderCreate to create a WMI provider object. It shows the typical steps for setting up a WMI provider in a WDF driver. ```C WDF_WMI_PROVIDER_CONFIG config; WDFWMIPROVIDER provider; GUID providerGuid = MY_WMI_DATA_BLOCK_GUID; NTSTATUS status; WDF_WMI_PROVIDER_CONFIG_INIT( &config, providerGuid ); config.Flags = WdfWmiProviderTracing; config.EvtWmiProviderFunctionControl = MyProviderFunctionControl; status = WdfWmiProviderCreate( Device, &config, WDF_NO_OBJECT_ATTRIBUTES, &provider ); ``` -------------------------------- ### WDF_WMI_INSTANCE_CONFIG Structure API Reference Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfwmi/ns-wdfwmi-_wdf_wmi_instance_config Detailed API documentation for the WDF_WMI_INSTANCE_CONFIG structure, outlining its role as input for WdfWmiInstanceCreate and the recommended initialization functions. It also includes system requirements and a list of related WMI functions and structures. ```APIDOC WDF_WMI_INSTANCE_CONFIG Structure: Description: Used as input to the WdfWmiInstanceCreate method. Initialization: - WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER - WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG Requirements: - Minimum KMDF version: 1.0 - Header: wdfwmi.h (include Wdf.h) Related Functions/Structures: - EvtWmiInstanceExecuteMethod - EvtWmiInstanceQueryInstance - EvtWmiInstanceSetInstance - EvtWmiInstanceSetItem - WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER - WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG - WDF_WMI_PROVIDER_CONFIG - WdfWmiInstanceCreate - WdfWmiInstanceRegister - WdfWmiProviderCreate ``` -------------------------------- ### Modify Driver File Name in INF/INX Device Install Section Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This INF/INX snippet demonstrates how the driver file is specified in the device install section. The "wdffeatured.sys" file name must be changed to the name of your generated driver file when adapting sample code. This ensures Setup copies the correct driver binary. ```INF [Toaster_Device.NT] CopyFiles=Toaster_Device.NT.Copy [Toaster_Device.NT.Copy] wdffeatured.sys ``` -------------------------------- ### Example INF File for a Simple Driver Package Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-version-section This INF file example demonstrates a typical [Version] section for a simple driver package, including directives for signature, class, provider, catalog file, and driver version. It also shows the implied [SourceDisksNames], [SourceDisksFiles.x86], and [Strings] sections, which define disk layout, file locations, and string definitions necessary for driver installation. ```INF [Version] Signature="$Windows NT$" Class=SCSIAdapter ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318} Provider=%INF_Provider% CatalogFile=example.cat DriverVer=01/29/2010,1.2.3.4 PnpLockdown=1 [SourceDisksNames] ; ; diskid = description[, [tagfile] [, , subdir]] ; 1 = %Disk_Description%,,,\\WinNT [SourceDisksFiles.x86] ; ; filename_on_source = diskID[, [subdir][, size]] ; exampleDriver.sys = 1,\\x86 ; ... [Strings] INF_Provider="Contoso" Disk_Description = "Contoso Drivers Disk" ; ... ``` -------------------------------- ### Implement WDF DriverEntry and EvtDeviceAdd Callbacks Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/writing-your-first-driver This snippet provides the C code for the DriverEntry function, which is the initial entry point for a WDF driver, and the KmdfHelloWorldEvtDeviceAdd callback, responsible for creating the device object. It illustrates the basic setup for a kernel-mode driver, demonstrating how WDF drivers are a collection of callbacks. ```C NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { // NTSTATUS variable to record success or failure NTSTATUS status = STATUS_SUCCESS; // Allocate the driver configuration object WDF_DRIVER_CONFIG config; // Print "Hello World" for DriverEntry KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n" )); // Initialize the driver configuration object to register the // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd ); // Finally, create the driver object status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE ); return status; } NTSTATUS KmdfHelloWorldEvtDeviceAdd( _In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit ) { // We're not using the driver object, // so we need to mark it as unreferenced UNREFERENCED_PARAMETER(Driver); NTSTATUS status; // Allocate the device object WDFDEVICE hDevice; // Print "Hello World" KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: KmdfHelloWorldEvtDeviceAdd\n" )); // Create the device object status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &hDevice ); return status; } ``` -------------------------------- ### C++ Example: Enumerate All Transaction Objects Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdm/nf-wdm-ntenumeratetransactionobject This C++ code example demonstrates how to enumerate all transaction objects on a computer using ZwEnumerateTransactionObject. It initializes a KTMOBJECT_CURSOR structure, repeatedly calls the routine to retrieve one GUID at a time, converts the GUID to a Unicode string, and displays it. ```C++ NTSTATUS Status; UNICODE_STRING GuidString; KTMOBJECT_CURSOR Cursor; ULONG ReturnedBytes; RtlZeroMemory(&Cursor, sizeof(Cursor)); do { Status = ZwEnumerateTransactionObject( NULL, KTMOBJECT_TRANSACTION, &Cursor, sizeof(Cursor), &ReturnedBytes ); if (Status != STATUS_NO_MORE_ENTRIES) { RtlStringFromGUID( &Cursor.ObjectIds[0], &GuidString ); OutputMessage(GuidString.Buffer); OutputMessage(L"\r\n"); RtlFreeUnicodeString(&GuidString); } } while (Status == STATUS_SUCCESS); if (Status == STATUS_NO_MORE_ENTRIES) { Status = STATUS_SUCCESS; } ``` -------------------------------- ### Display CodeQL CLI Help Information Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/devtest/static-tools-and-codeql Shows the general usage, common options, and available commands for the CodeQL command-line tool. It provides an overview of CodeQL's capabilities. ```Batch C:\codeql-home\codeql\>codeql --help ``` -------------------------------- ### Define WMI Event GUID for Driver Notifications Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This C/C++ example shows how to define a GUID for custom Windows Management Instrumentation (WMI) events, such as device arrival notifications. Each WMI event in your driver should have a unique GUID to ensure proper event identification and handling. ```C/C++ DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT, \ 0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, \ 0x27, 0x25, 0xe2, 0x9c); // {01CDAFF1-C901-45b4-B359-B5542725E29C} ``` -------------------------------- ### INF Configuration for Driver Service Name Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This snippet shows how to update the service name using the AddService directive in an INF file. It is crucial to use a unique service name to avoid conflicts with other drivers, which could prevent installation or loading. The example is from the KMDF Featured Toaster driver, demonstrating where to specify the service name. ```INF [Toaster_Device.NT.Services] AddService = wdffeatured, %SPSVCINST_ASSOCSERVICE%, wdffeatured_Service_Inst ``` -------------------------------- ### C/C++ Example: Initializing WDF_DEVICE_POWER_CAPABILITIES and Calling WdfDeviceSetPowerCapabilities Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdfdevicesetpowercapabilities This C/C++ code example demonstrates how to initialize a WDF_DEVICE_POWER_CAPABILITIES structure with specific power states and then call the WdfDeviceSetPowerCapabilities function to report these capabilities to the framework. ```C++ WDF_DEVICE_POWER_CAPABILITIES powerCaps; WDF_DEVICE_POWER_CAPABILITIES_INIT(&powerCaps); powerCaps.DeviceD1 = WdfTrue; powerCaps.WakeFromD1 = WdfTrue; powerCaps.DeviceWake = PowerDeviceD1; powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD1; powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD1; powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD2; powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD2; powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3; powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3; WdfDeviceSetPowerCapabilities( device, &powerCaps ); ``` -------------------------------- ### Batch File for WinDbg COM Port Debugging Setup Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/debugger/performing-kernel-mode-debugging-using-windbg This batch file sets up environment variables for WinDbg, including symbol path, COM port, baud rate, and a log file, then starts WinDbg in kernel mode. ```Batch set _NT_SYMBOL_PATH=d:\mysymbols set _NT_DEBUG_PORT=com1 set _NT_DEBUG_BAUD_RATE=115200 set _NT_DEBUG_LOG_FILE_OPEN=d:\debuggers\logfile1.log windbg -k ``` -------------------------------- ### Implement DRIVER_STARTIO Callback Routine Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdm/nc-wdm-driver_startio Example of implementing a DRIVER_STARTIO callback routine, MyStartIo, including the _Use_decl_annotations_ for code analysis and verifier tools, demonstrating the function body structure. ```C _Use_decl_annotations_ VOID MyStartIo( struct _DEVICE_OBJECT *DeviceObject, struct _IRP *Irp ) { // Function body } ``` -------------------------------- ### Example KMDF Device Installation Directives Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/wdf/specifying-wdf-directives-in-inf-files An example of KMDF-specific directives within the DDInstall.WDF section of an INF file, showing how to specify the KMDF service. ```INF [ECHO_Device.NT.Wdf] KmdfService = Echo, Echo_service_wdfsect ``` -------------------------------- ### Setup CodeQL Environment for Driver Analysis Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/devtest/static-tools-and-codeql Commands for setting up the necessary environment for CodeQL driver analysis, including cloning the supplemental tools repository and creating a dedicated directory for databases. These steps are prerequisites for building and analyzing CodeQL databases. ```Shell git clone https://github.com/microsoft/Windows-Driver-Developer-Supplemental-Tools.git --recurse-submodules ``` ```Shell mkdir C:\codeql-home\databases ``` -------------------------------- ### Example: Opening an I/O Target with Existing Device Object Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfiotarget/nf-wdfiotarget-wdf_io_target_open_params_init_existing_device This code example demonstrates how to create an I/O target object and open it by specifying an existing Windows Driver Model (WDM) DEVICE_OBJECT structure. It shows the initialization of WDF_IO_TARGET_OPEN_PARAMS and the subsequent call to WdfIoTargetOpen. ```C++ WDF_IO_TARGET_OPEN_PARAMS openParams; NTSTATUS ntStatus; ntStatus = WdfIoTargetCreate( Adapter->WdfDevice, WDF_NO_OBJECT_ATTRIBUTES, &Adapter->IoTarget ); if (!NT_SUCCESS(ntStatus)) { DEBUGP(MP_ERROR, ("WdfIoTargetCreate failed 0x%x\n", ntStatus)); break; } WDF_IO_TARGET_OPEN_PARAMS_INIT_EXISTING_DEVICE( &openParams, Adapter->NextDeviceObject ); ntStatus = WdfIoTargetOpen(Adapter->IoTarget, &openParams); if (!NT_SUCCESS(ntStatus)) { DEBUGP(MP_ERROR, ("WdfIoTargetOpen failed 0x%x\n", ntStatus)); break; } ``` -------------------------------- ### INF Configuration for Hardware ID and Compatible ID Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This example from the KMDF Featured Toaster driver illustrates how to specify hardware IDs in the INF file. Hardware IDs are less specific than device IDs and are used by Setup if a direct device ID match is not found. This snippet shows the structure for defining these IDs, which should be adapted for other supported devices. ```INF [Manufacturer] %StdMfg%=Standard,NT$ARCH$ ; For Win2K [Standard] ; DisplayName Section DeviceId ; ----------- ------- -------- %ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster ; For XP and later [Standard.NT$ARCH$] %ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster ``` -------------------------------- ### Common WinDbg Kernel Debugger Commands Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/writing-your-first-driver Examples of basic commands to use within a WinDbg kernel debugging session (kd>) for listing modules, setting symbol paths, reloading modules, and examining symbols. ```WinDbg lm ``` ```WinDbg .sympath ``` ```WinDbg .reload ``` ```WinDbg x KmdfHelloWorld!\* ``` -------------------------------- ### Successful KMDF Driver Installation Log Output Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/wdf/debugging-driver-installation This log output from the Setup action log illustrates a successful installation of a KMDF driver. It shows that the on-disk and in-memory KMDF versions are consistent with the co-installer's version, indicating that no update was necessary. ```Log WdfCoInstaller: DIF_INSTALLDEVICE: Pre-Processing WdfCoInstaller: ReadComponents: WdfSection for Driver Service ECHO using KMDF lib version Major 0x1, minor 0x9 WdfCoInstaller: DIF_INSTALLDEVICE: Coinstaller version: 1.9.7100 WdfCoInstaller: DIF_INSTALLDEVICE: KMDF in-memory version: 1.9.7100 WdfCoInstaller: DIF_INSTALLDEVICE: KMDF on-disk version: 1.9.7100 WdfCoInstaller: Service Wdf01000 is running WdfCoInstaller: DIF_INSTALLDEVICE: Update is not required. The on-disk KMDF version is newer than or same as the version of the coinstaller WdfCoInstaller: DIF_INSTALLDEVICE: Post-Processing ``` -------------------------------- ### PropKeyFindKeyGetGuid Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/_sensors This routine gets a GUID value from a PROPVARIANT within a collection list based on the PROPERTYKEY. ```APIDOC PropKeyFindKeyGetGuid: This routine gets a GUID value from a PROPVARIANT within a collection list based on the PROPERTYKEY. ``` -------------------------------- ### WDF_USB_CONTROL_SETUP_PACKET_INIT Function API Documentation Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfusb/nf-wdfusb-wdf_usb_control_setup_packet_init Detailed API documentation for the WDF_USB_CONTROL_SETUP_PACKET_INIT function, including parameter descriptions, return value, and remarks on its behavior and related functions for initializing USB control setup packets in WDF. ```APIDOC WDF_USB_CONTROL_SETUP_PACKET_INIT: Applies to: KMDF and UMDF Purpose: Initializes a WDF_USB_CONTROL_SETUP_PACKET structure for a standard USB control transfer. Parameters: Packet [out]: A pointer to a WDF_USB_CONTROL_SETUP_PACKET structure. Direction [in]: A WDF_USB_BMREQUEST_DIRECTION-typed value that is stored in the Packet.bm.Request.Dir member of the WDF_USB_CONTROL_SETUP_PACKET structure. Recipient [in]: A WDF_USB_BMREQUEST_RECIPIENT-typed value that is stored in the Packet.bm.Request.Recipient member of the WDF_USB_CONTROL_SETUP_PACKET structure. Request [in]: A request type constant that is stored in the Packet.bRequest member of the WDF_USB_CONTROL_SETUP_PACKET structure. Value [in]: A request-specific value that is stored in the Packet.wValue.Value member of the WDF_USB_CONTROL_SETUP_PACKET structure. Index [in]: A request-specific index value that is stored in the Packet.wIndex.Value member of the WDF_USB_CONTROL_SETUP_PACKET structure. Return Value: None Remarks: The WDF_USB_CONTROL_SETUP_PACKET_INIT function does the following: 1. Zeros the WDF_USB_CONTROL_SETUP_PACKET structure. 2. Sets the Packet.bm.Request.Type member to BmRequestStandard. 3. Sets other structure members by using the WDF_USB_CONTROL_SETUP_PACKET_INIT function's input arguments. To initialize a WDF_USB_CONTROL_SETUP_PACKET structure, the driver should call one of the following functions: - WDF_USB_CONTROL_SETUP_PACKET_INIT - WDF_USB_CONTROL_SETUP_PACKET_INIT_CLASS - WDF_USB_CONTROL_SETUP_PACKET_INIT_FEATURE - WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS - WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR ``` -------------------------------- ### C Example: Get USB Endpoint Information Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfusb/nf-wdfusb-wdfusbinterfacegetendpointinformation This C code example demonstrates how to iterate through the endpoints of a USB interface using WdfUsbInterfaceGetNumEndpoints and then retrieve detailed information for each endpoint using WdfUsbInterfaceGetEndpointInformation. ```C WDF_USB_PIPE_INFORMATION endPointInfo; BYTE settingIndex, i; settingIndex = 0; numEndpoints = WdfUsbInterfaceGetNumEndpoints( UsbInterface, settingIndex ); for (i = 0; i < numEndpoints; i++){ WDF_USB_PIPE_INFORMATION_INIT(&endPointInfo); WdfUsbInterfaceGetEndpointInformation( UsbInterface, settingIndex, i, &endPointInfo ); // // Examine endpoint information here. // ... } ``` -------------------------------- ### Example: Get WDM Physical Device Object (PDO) in C Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdffdo/nf-wdffdo-wdffdoinitwdmgetphysicaldevice This code example demonstrates how to call WdfFdoInitWdmGetPhysicalDevice to obtain a pointer to a DEVICE_OBJECT structure, which represents a device's WDM PDO. ```C PDEVICE_OBJECT device; device = WdfFdoInitWdmGetPhysicalDevice(DeviceInit); ``` -------------------------------- ### COM Client API Calls for Device Catalog Registration Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-ddinstall-com-section This API documentation describes the essential COM API calls required for clients to access COM servers registered via INF. It details CoRegisterDeviceCatalog for making server registrations available and CoCreateInstance for creating COM object instances. ```APIDOC CoRegisterDeviceCatalog: Purpose: Makes COM server registrations available in the process for the COM runtime to use. Usage: Must be called on a worker thread before CoCreateInstance. CoCreateInstance: Purpose: Creates an uninitialized object of the class associated with a specified CLSID. Usage: Used to create instances of COM objects after registrations are available via CoRegisterDeviceCatalog. ``` -------------------------------- ### WdfIoTargetStart Function API Reference Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfiotarget/nf-wdfiotarget-wdfiotargetstart Comprehensive API documentation for the WdfIoTargetStart method, used to start sending queued requests to a local or remote I/O target in WDF drivers. It details the function signature, parameters, return values, and general remarks. ```APIDOC WdfIoTargetStart(IoTarget: WDFIOTARGET) -> NTSTATUS Parameters: IoTarget [in]: A handle to a local or remote I/O target object obtained from WdfDeviceGetIoTarget, WdfIoTargetCreate, or a specialized I/O target method. Return Value: NTSTATUS: STATUS_SUCCESS: The operation succeeded. STATUS_INVALID_DEVICE_STATE: The device has been removed. Other NTSTATUS values: Possible additional error codes. Remarks: - Call WdfIoTargetStart to resume sending requests after WdfIoTargetStop. - Required in EvtDeviceD0Entry if WdfUsbTargetPipeConfigContinuousReader is used for a USB pipe. - Calls to WdfIoTargetStart and WdfIoTargetStop must be synchronous. - A bug check occurs if an invalid object handle is supplied. Requirements: Target Platform: Universal Minimum KMDF version: 1.0 Minimum UMDF version: 2.0 Header: wdfiotarget.h (include Wdf.h) Library: Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) IRQL: <=DISPATCH_LEVEL DDI compliance rules: DriverCreate(kmdf), FailD0EntryIoTargetState(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf) ``` -------------------------------- ### Example: Get WDF Driver Registry Path Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdriver/nf-wdfdriver-wdfdrivergetregistrypath This code example demonstrates how to obtain the path to a driver's registry key in the registry's Services tree using the WdfDriverGetRegistryPath function. ```C PWSTR registryPath; registryPath = WdfDriverGetRegistryPath(driver); ``` -------------------------------- ### Initialize WDF_DEVICE_PNP_CAPABILITIES and Call WdfDeviceSetPnpCapabilities Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdfdevicesetpnpcapabilities This example demonstrates how to initialize a WDF_DEVICE_PNP_CAPABILITIES structure and then call WdfDeviceSetPnpCapabilities to set the device's Plug and Play capabilities, specifically enabling surprise removal. ```C WDF_DEVICE_PNP_CAPABILITIES pnpCaps; WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps); pnpCaps.SurpriseRemovalOK = WdfTrue; WdfDeviceSetPnpCapabilities( device, &pnpCaps ); ``` -------------------------------- ### INF Configuration for PnP Device ID Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This snippet demonstrates how to define the device ID in the [Manufacturer] section of an INF file. The device ID uniquely identifies a specific device and is used by Setup to match the device with the correct INF. It shows an example for the OSR USB Fx2 device, highlighting where to replace the vendor and product IDs with your own device's information. ```INF [Manufacturer] %MfgName%=Microsoft,NT$ARCH$ ; For Win2K [Microsoft] %USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, USB\VID_0547&PID_1002 ... ; For XP and later [Microsoft.NT$ARCH$] %USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, USB\VID_0547&PID_1002 ``` -------------------------------- ### Example UMDF Service Installation Directives Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/wdf/specifying-wdf-directives-in-inf-files An example of UMDF-specific directives within the [wdf-service-install] section of an INF file, showing how to specify the UMDF library version and the service binary path. ```INF [Echo_service_wdfsect] UmdfLibraryVersion = $UMDFVERSION$ ServiceBinary = %13%\echo.dll ``` -------------------------------- ### Example EvtDeviceFileCreate callback to get file name Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdffileobject/nf-wdffileobject-wdffileobjectgetfilename This C code example demonstrates how an EvtDeviceFileCreate callback function can use WdfFileObjectGetFileName to obtain the name of the file that an application has opened, typically during a file creation request. ```C VOID MyEvtDeviceFileCreate ( IN WDFDEVICE Device, IN WDFREQUEST Request, IN WDFFILEOBJECT FileObject ) { PUNICODE_STRING fileName; fileName = WdfFileObjectGetFileName(FileObject); ... } ``` -------------------------------- ### WdfDeviceInitSetDeviceClass Method Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice The WdfDeviceInitSetDeviceClass method specifies a GUID that identifies the device's device setup class. ```APIDOC WdfDeviceInitSetDeviceClass: Description: Specifies a GUID that identifies the device's device setup class during initialization. ``` -------------------------------- ### C/C++ Example: Initialize WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS and Call WdfDeviceAssignSxWakeSettings Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdfdeviceassignsxwakesettings This C/C++ code example demonstrates how to initialize a WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS structure using WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT and then call WdfDeviceAssignSxWakeSettings to configure device wake settings. It includes basic error handling. ```C++ WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings; NTSTATUS status = STATUS_SUCCESS; WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings); status = WdfDeviceAssignSxWakeSettings( device, &wakeSettings ); if (!NT_SUCCESS(status)) { return status; } ``` -------------------------------- ### Example: Get Number of USB Interface Alternate Settings Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfusb/nf-wdfusb-wdfusbinterfacegetnumsettings This code example demonstrates how to call the WdfUsbInterfaceGetNumSettings function to obtain the number of alternate settings available for a specified USB interface. The result is stored in a BYTE variable. ```C++ BYTE altSettings; altSettings = WdfUsbInterfaceGetNumSettings(UsbInterface); ``` -------------------------------- ### WDF_POWER_FRAMEWORK_SETTINGS_INIT API Reference Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdf_power_framework_settings_init Detailed API documentation for the WDF_POWER_FRAMEWORK_SETTINGS_INIT function, including its parameters, return value, remarks, and system requirements for KMDF drivers. ```APIDOC Function: WDF_POWER_FRAMEWORK_SETTINGS_INIT Parameters: PowerFrameworkSettings [out]: A pointer to a driver-allocated WDF_POWER_FRAMEWORK_SETTINGS structure. Return Value: None Remarks: The WDF_POWER_FRAMEWORK_SETTINGS_INIT function zeros the specified WDF_POWER_FRAMEWORK_SETTINGS structure and sets the structure's Size member. Requirements: Target Platform: Universal Minimum KMDF version: 1.11 Header: wdfdevice.h (include Wdf.h) See also: WDF_POWER_FRAMEWORK_SETTINGS WdfDeviceWdmAssignPowerFrameworkSettings ``` -------------------------------- ### Registering a WDM Client Driver with USBD_CreateHandle Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/usbdlib/nf-usbdlib-usbd_createhandle This C code example demonstrates the MyAddDevice routine, which is a typical entry point for a Windows Driver Model (WDM) client driver. It illustrates the process of creating a device object, attaching it to the device stack, and crucially, registering the client driver with the USB driver stack by calling USBD_CreateHandle. The example also includes a call to USBD_QueryUsbCapability to determine stream support. ```C DRIVER_ADD_DEVICE MyAddDevice; NTSTATUS MyAddDevice( __in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; PDEVICE_OBJECT stackDeviceObject; USBD_HANDLE usbdHandle; ... ntStatus = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &deviceObject); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } ... // Attach the FDO to the top of the PDO in the client driver's // device stack. deviceExtension->StackDeviceObject = IoAttachDeviceToDeviceStack ( deviceObject, PhysicalDeviceObject); ... // Initialize the DeviceExtension deviceExtension = deviceObject->DeviceExtension; ... //Register the client driver with the USB driver stack. //Obtain a USBD handle for registration. ntStatus = USBD_CreateHandle(deviceObject, deviceExtension->StackDeviceObject, USBD_CLIENT_CONTRACT_VERSION_602, POOL_TAG, &deviceExtension->USBDHandle); if (!NT_SUCCESS(ntStatus)) { return ntStatus; } ... // Call USBD_QueryUsbCapability to determine // stream support. ntStatus = USBD_QueryUsbCapability ( deviceExtension->USBDHandle, (GUID*)&GUID_USB_CAPABILITY_STATIC_STREAMS, sizeof(ULONG), (PUCHAR) &deviceExtension.MaxSupportedStreams); if (!NT_SUCCESS(ntStatus)) { deviceExtension->MaxSupportedStreams = 0; ntStatus = STATUS_SUCCESS; } ... } ``` -------------------------------- ### Example: Calling NtPowerInformation to get Platform Information Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/ntddk/nf-ntddk-zwpowerinformation This example illustrates a valid function call to the NtPowerInformation routine, demonstrating how to retrieve system platform power capabilities by initializing a POWER_PLATFORM_INFORMATION structure and passing it as the output buffer. ```C/C++ POWER_PLATFORM_INFORMATION PlatformInfo = {0}; NTSTATUS Result = NtPowerInformation(PlatformInformation, NULL, 0, &PlatformInfo, sizeof(PlatformInfo)); ``` -------------------------------- ### Initialize WMI Provider and Instance Configuration in KMDF Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfwmi/nf-wdfwmi-wdf_wmi_instance_config_init_provider This C code example demonstrates the typical workflow for setting up WMI data blocks in a Kernel-Mode Driver Framework (KMDF) driver. It initializes a WMI provider configuration, creates a WMI provider object using WdfWmiProviderCreate, then initializes a WMI instance configuration using WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER, and finally creates a WMI instance with WdfWmiInstanceCreate. ```C WDF_WMI_PROVIDER_CONFIG providerConfig; WDFWMIPROVIDER provider; GUID providerGuid = MY_WMI_DATA_BLOCK_GUID; WDF_WMI_INSTANCE_CONFIG instanceConfig; WDFWMIINSTANCE instanceHandle; NTSTATUS status; WDF_WMI_PROVIDER_CONFIG_INIT( &providerConfig, providerGuid ); providerConfig.Flags = WdfWmiProviderTracing; providerConfig.EvtWmiProviderFunctionControl = MyProviderFunctionControl; status = WdfWmiProviderCreate( Device, &providerConfig, WDF_NO_OBJECT_ATTRIBUTES, &provider ); if (!NT_SUCCESS(status)) { return status; } WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER( &instanceConfig, provider ); status = WdfWmiInstanceCreate( Device, &instanceConfig, WDF_NO_OBJECT_ATTRIBUTES, &instanceHandle ); if (!NT_SUCCESS(status)) { return status; } ``` -------------------------------- ### Modify Class Installer File Names in INF/INX Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/from-sample-code-to-production-driver This INF/INX snippet shows how to specify a class installer DLL and its entry point. When adapting sample code, the "tostrcls.dll" and "ToasterClassInstaller" strings must be changed to reflect the actual file name and installer function of your custom class installer. This ensures the correct co-installer file is copied and registered. ```INF [ClassInstall32] Addreg=ToasterClassReg CopyFiles=ToasterClassInstallerCopyFileshighlight [ToasterClassReg] ... HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller" ... [ToasterClassInstallerCopyFiles] tostrcls.dll ... ``` -------------------------------- ### Create CodeQL Home Directory Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/devtest/static-tools-and-codeql Creates a new directory on the C drive to house the CodeQL CLI installation files. ```Batch C:\> mkdir C:\codeql-home ``` -------------------------------- ### C Example: Retrieving Input Buffer MDL in EvtIoWrite Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfrequest/nf-wdfrequest-wdfrequestretrieveinputwdmmdl Illustrates how a KMDF driver uses WdfRequestRetrieveInputWdmMdl within an EvtIoWrite callback to get an MDL for the input buffer. The example includes error checking and request completion logic. ```C VOID MyDrvEvtIoWrite( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length ) { NTSTATUS status; PMDL mdl = NULL; ... status = WdfRequestRetrieveInputWdmMdl( Request, &mdl ); if (!NT_SUCCESS(status)) { WdfRequestCompleteWithInformation( Request, status, 0 ); } ... } ``` -------------------------------- ### Example: Calling WdfDeviceInitSetPowerInrush in KMDF Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdfdevice/nf-wdfdevice-wdfdeviceinitsetpowerinrush A simple code example demonstrating how to call the WdfDeviceInitSetPowerInrush function. This call informs the power manager that the device requires an inrush of current when it starts, typically performed during the device initialization phase in a KMDF driver. ```C WdfDeviceInitSetPowerInrush(DeviceInit); ``` -------------------------------- ### IoStartPacket Function API Documentation Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/ntifs/nf-ntifs-iostartpacket Comprehensive API documentation for the IoStartPacket routine, including its signature, parameters, return value, usage remarks, and system requirements for Windows driver development. ```APIDOC IoStartPacket function (ntifs.h) Syntax: void IoStartPacket( [in] PDEVICE_OBJECT DeviceObject, [in] PIRP Irp, [in, optional] PULONG Key, [in, optional] PDRIVER_CANCEL CancelFunction ); Parameters: DeviceObject [in]: Pointer to the target device object for the IRP. Irp [in]: Pointer to the IRP to be processed. Key [in, optional]: Pointer to a value that determines where to insert the packet into the device queue. If zero, the packet is inserted at the tail. CancelFunction [in, optional]: Specifies the entry point for a driver-supplied Cancel routine. Return value: None Remarks: - If the driver is busy, the packet is queued; otherwise, the driver's StartIo routine is called. - If a non-NULL CancelFunction is supplied, it is set in the IRP for cancellation handling. - Drivers without a StartIo routine cannot call IoStartPacket. - Callers must be running at IRQL <= DISPATCH_LEVEL (usually from Dispatch routine at IRQL = PASSIVE_LEVEL). Requirements: Minimum supported client: Windows 2000 Target Platform: Universal Header: ntifs.h (include Wdm.h, Ntddk.h, Ntifs.h) Library: NtosKrnl.lib DLL: NtosKrnl.exe IRQL: <= DISPATCH_LEVEL See also: DEVICE_OBJECT IoMarkIrpPending IoSetCancelRoutine IoStartNextPacket IoStartNextPacketByKey ``` -------------------------------- ### INF Class Entry Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/install/inf-version-section Specifies the name of the device setup class for the device installed by the INF file. This can be a system-defined class name or a new, unique class name. This entry is required for device drivers installed through the Plug and Play (PnP) manager. ```APIDOC Class=class-name class-name: string Description: Name of the device setup class. Usage: - For standard device types: System-defined class names (e.g., Net, Display) from Devguid.h. - For new setup classes: A unique, case-insensitive value (max 32 characters) different from system-supplied classes. Requirements: - If Class is specified, ClassGUID should also be specified with the corresponding system-defined GUID for faster installation. - If adding a new setup class, a newly generated GUID value for ClassGUID is required. Notes: - Irrelevant if the INF installs neither a new device driver under a predefined class nor a new device setup class. - Required for device drivers installed through the Plug and Play (PnP) manager. ``` -------------------------------- ### Implement the DriverEntry function for a KMDF driver Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/gettingstarted/writing-your-first-driver Provides the implementation for the DriverEntry function, the primary entry point for the driver. It initializes driver-wide structures, prints a 'Hello World' message, configures the driver object to register the EvtDeviceAdd callback, and creates the driver object. ```C NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { // NTSTATUS variable to record success or failure NTSTATUS status = STATUS_SUCCESS; // Allocate the driver configuration object WDF_DRIVER_CONFIG config; // Print "Hello World" for DriverEntry KdPrintEx(( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "KmdfHelloWorld: DriverEntry\n" )); // Initialize the driver configuration object to register the // entry point for the EvtDeviceAdd callback, KmdfHelloWorldEvtDeviceAdd WDF_DRIVER_CONFIG_INIT(&config, KmdfHelloWorldEvtDeviceAdd ); // Finally, create the driver object status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE ); return status; } ``` -------------------------------- ### KSTART_ROUTINE Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/ddi/wdm The ThreadStart routine provides an entry point for a driver-created system thread. ```APIDOC KSTART_ROUTINE: The ThreadStart routine provides an entry point for a driver-created system thread. ``` -------------------------------- ### DevCon: General Syntax for Driver Installation Source: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/iddcx/debugger/debug-universal-drivers---step-by-step-lab--echo-kernel-mode- Illustrates the general command-line syntax for using the DevCon tool to install a driver, requiring the INF file path and the hardware ID. ```Batch devcon install ```