How to open device driver for IOCTL

-1

I am trying to open a device driver in order to send it an ioctl. There are many examples on SO and elsewhere but virtually all address opening "\\.\PhysicalDrive0" or the like. But I am trying to open a non-disk driver, compiled from Microsoft sample code at GitHub "Windows-driver-samples", namely "simgpio". It appears to have installed correctly but I don't know what "\\.\name" to use. I tried "\\.\simgpio" with no joy. Suggestions?

For reference, I've included the driver's .INF file below.

;/*++
;
;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
windows
device-driver
createfile
asked on Stack Overflow Jul 3, 2020 by DontPanic • edited Aug 8, 2020 by jonrsharpe

1 Answer

0

Thanks to comment by @Eryk, I was able to open a driver. I include a sample program below. All error checking was omitted for clarity. I used the CDROM driver class in this example. The real challenge is finding the elusive GUID to use - you must do some deep digging in the SDK, DDK, include files or your driver.

//  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();
}

Here are some other GUIDs you can use:

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} };  
answered on Stack Overflow Jul 17, 2020 by DontPanic • edited Jul 18, 2020 by DontPanic

User contributions licensed under CC BY-SA 3.0