-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
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
DontPanic
  • 2,164
  • 5
  • 29
  • 56
  • A couple decades ago it was decided that letting drivers arbitrarily name devices was too chaotic. You need to find the device interface class GUID in the system header for the interface class that you're implementing, which I suppose in your case is `GUID_GPIO_INTERFACE` defined in "km/i2cgpio.h". Build a device information set for the interface class via `SetupDiGetClassDevsW`; enumerate the devices via `SetupDiEnumDeviceInterfaces`; and get the path to open for each device via `SetupDiGetDeviceInterfaceDetailW`. – Eryk Sun Jul 04 '20 at 04:18
  • Thanks. That worked. – DontPanic Dec 22 '20 at 16:02

1 Answers1

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} };  
DontPanic
  • 2,164
  • 5
  • 29
  • 56