【问题标题】:How to open device driver for IOCTL如何打开 IOCTL 的设备驱动程序
【发布时间】:2020-07-03 14:40:55
【问题描述】:

我正在尝试打开设备驱动程序以向其发送 ioctl。在 SO 和其他地方有很多例子,但几乎所有地址都打开 "\\.\PhysicalDrive0" 等。但我正在尝试打开一个非磁盘驱动程序,该驱动程序是从 GitHub 上的 Microsoft 示例代码“Windows-driver-samples”编译而来,即“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

【问题讨论】:

  • 几十年前,人们认为让司机随意命名设备太混乱了。您需要在系统标头中为您正在实现的接口类找到设备接口类 GUID,我想在您的情况下是在“km/i2cgpio.h”中定义的GUID_GPIO_INTERFACE。通过SetupDiGetClassDevsW为接口类建立设备信息集;通过SetupDiEnumDeviceInterfaces枚举设备;并通过SetupDiGetDeviceInterfaceDetailW获取每个设备的打开路径。
  • 谢谢。那行得通。

标签: windows device-driver createfile


【解决方案1】:

感谢@Eryk 的评论,我能够打开驱动程序。我在下面包含一个示例程序。为清楚起见,省略了所有错误检查。我在这个例子中使用了 CDROM 驱动程序类。真正的挑战是找到难以捉摸的 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} };  

【讨论】:

    猜你喜欢
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2012-01-05
    • 1970-01-01
    相关资源
    最近更新 更多