如何打开 IOCTL 的设备驱动程序

How to open device driver for IOCTL

我正在尝试打开一个设备驱动程序以便向它发送 ioctl。 SO 和其他地方有很多示例,但几乎所有地址都打开 "\\.\PhysicalDrive0" 等。但是我试图打开一个非磁盘驱动程序,它是从GitHub“Windows-driver-samples”处的Microsoft示例代码编译而来的,即“simgpio”。它似乎已正确安装,但我不知道要使用什么“\\.\name”。我尝试了 "\\.\simgpio" 但并不开心。建议?

作为参考,我在下面包含了驱动程序的 .INF 文件。

;/*++
;
;Copyright (c) Microsoft Corporation.  All rights reserved.
;
;Module Name:
;
;    SIMGPIO.INF
;
;Abstract:
;    INF file for installing Simulated GPIO Client Driver.
;
;--*/

[Version]
Signature="$WINDOWS NT$"
Class=System
ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318}
Provider=%ProviderName%
DriverVer = 06/30/2020,15.29.58.35
CatalogFile=gpiosamples.cat

[SourceDisksNames]
3426=windows cd

[SourceDisksFiles]
simgpio.sys = 3426

[DestinationDirs]
DefaultDestDir = 12

[ControlFlags]
BasicDriverOk = *
ExcludeFromSelect = *

;******************************************
; SIMGPIO Client driver Install Section
;******************************************

[Manufacturer]
%ManufacturerName%=Standard,NTx86

[Standard.NTx86]
%GPIO.DeviceDesc% = GPIO_Inst,ACPI\TEST0001

[GPIO_Inst.NT]
Copyfiles = GPIOCopyFiles

[GPIOCopyFiles]
simgpio.sys,,,0x100

[GPIO_Inst.NT.Services]
AddService = simgpio,%SPSVCINST_ASSOCSERVICE%,GPIO_Service_Inst

[GPIO_Service_Inst]
DisplayName    = %GPIO.SvcDesc%
ServiceType    = %SERVICE_KERNEL_DRIVER%
StartType      = %SERVICE_DEMAND_START%
ErrorControl   = %SERVICE_ERROR_NORMAL%
ServiceBinary  = %12%\simgpio.sys

[strings]
; localizable strings
ProviderName        = "TODO-Set-Provider"
ManufacturerName    = "TODO-Set-Manufacturer"
GPIO.DeviceDesc     = "Simulated GPIO Client Driver"
GPIO.SvcDesc        = "Simulated GPIO Client Driver"

; non-localizable strings
SPSVCINST_TAGTOFRONT   = 0x00000003
SPSVCINST_ASSOCSERVICE = 0x00000002
SERVICE_KERNEL_DRIVER  = 1
SERVICE_BOOT_START     = 0
SERVICE_SYSTEM_START   = 1
SERVICE_DEMAND_START   = 3
SERVICE_ERROR_NORMAL   = 1
SERVICE_ERROR_IGNORE   = 0
SERVICE_ERROR_CRITICAL = 3
REG_EXPAND_SZ          = 0x00020000
REG_DWORD              = 0x00010001
REG_SZ                 = 0x00000000

感谢@Eryk 的评论,我能够打开一个驱动程序。我在下面包含了一个示例程序。为清楚起见,省略了所有错误检查。我在这个例子中使用了 CDROM 驱动程序 class。真正的挑战是找到难以捉摸的 GUID 来使用——你必须深入挖掘 SDK、DDK、包含文件或你的驱动程序。

//  enumdevices.c - enumerate and open device(s)

#pragma warning( disable : 4090 )
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <setupapi.h>
#include <cfgmgr32.h>

int
main( int argc,char** argv)
{
    #define ALLOC(size)  GlobalAlloc( GPTR, size)

    SP_DEVINFO_DATA *devData;
    HANDLE devSet;
    HANDLE hDev;
    SP_DEVICE_INTERFACE_DATA *devIfData;
    SP_DEVICE_INTERFACE_DETAIL_DATA *Details;
    GUID *devGuid;
    DWORD needed;
    DWORD unused;
    int count;          // count of enumerated devices
    DWORD idev;         // device index
    DWORD iface;        // interface index
    char deviceID[200]; // device id string
    int IDSize;
    BOOL ok;

    devData = ALLOC(  sizeof(SP_DEVINFO_DATA) );
    devData->cbSize = sizeof(SP_DEVINFO_DATA);

    // GET SET OF DEVICE INTERFACES PRESENT OF SPECIFIED devGuid
    devGuid = &GUID_DEVINTERFACE_CDROM;     // set dev class guid to enumerate
    devSet = SetupDiGetClassDevs( devGuid, NULL, NULL, DIGCF_DEVICEINTERFACE|DIGCF_PRESENT );

    // OUTER LOOP
    idev  = 0;
    count = 0;
    while( TRUE ) {
        // GET DEVICE INFO DATA
        ok = SetupDiEnumDeviceInfo( devSet, idev, devData );
        if (!ok) break;
        
        // GET ID SIZE
        devData->cbSize = sizeof(SP_DEVINFO_DATA);
        CM_Get_Device_ID_Size( &IDSize, devData->DevInst, 0 );

        // GET DEVICE ID
        CM_Get_Device_ID( devData->DevInst, deviceID, 200, 0 );
        printf("Device Instance #%d: deviceId = \"%s\"\n", devData->DevInst, deviceID ); // print it
        count++;

        devIfData = ALLOC( sizeof(SP_DEVICE_INTERFACE_DATA) );
        devIfData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        iface = 0;                                  // init index
        while ( TRUE ) {                            // loop over all interfaces in set
            // GET DEVICE INTERFACE DATA index=iface
            ok = SetupDiEnumDeviceInterfaces(
                devSet,                 // handle to interface set
                devData,
                devGuid, //&GUID_DEVINTERFACE_USB_DEVICE, 
                iface,                              // interface index
                devIfData);
            if( !ok ) break;

            // GET NEEDED BUFFER SIZE
            devIfData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
            ok = SetupDiGetDeviceInterfaceDetail(
                devSet,
                devIfData,
                NULL,
                0,
                &needed,
                0 );

            Details = ALLOC( needed );
            Details->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);  // IMPORTANT!

            // GET DEVICE DETAILS
            ok = SetupDiGetDeviceInterfaceDetail(
                devSet,                 // device set
                devIfData,              // device info data
                Details,                // detail data
                needed,                 // size of Details
                &unused,                // unused
                NULL );                 // device info data (can be NULL)
            printf("%s\n", Details->DevicePath);        // announce

            // OPEN DEVICE
            hDev = CreateFile(Details->DevicePath,
                GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL, OPEN_EXISTING, 0, NULL);
            if( hDev != INVALID_HANDLE_VALUE ) {
              printf( "Device successfully opened\n" );
              // DO SOMETHING WITH DEVICE HANDLE (e.g., DeviceIoControl)...
              CloseHandle(hDev);
            }

            iface++;
        }

        idev++;     // next device
    }
    
    printf("\nenumerated %d device interfaces\n", count);
    fprintf(stderr, "Press any key to exit...\n");
    _getch();
}

以下是您可以使用的其他一些 GUID:

static GUID GUID_DEVINTERFACE_DISK =  
{ 0x4d36e967L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
static GUID GUID_DEVINTERFACE_USB_DEVICE =
{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };  
static GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER =  
{ 0x3abf6f2d, 0x71c4, 0x462a, {0x8a, 0x92, 0x1e, 0x68, 0x61, 0xe6, 0xaf, 0x27} };  
static GUID GUID_DEVINTERFACE_USB_HUB =
{ 0xf18a0e88, 0xc30c, 0x11d0, {0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8} };