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
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} };
User contributions licensed under CC BY-SA 3.0