-3

so I will detail so that we can easily understand

I have to make a driver for a pcie card, I already have the driver that I wrote in kmdf, now I am using this driver, unfortunately I find myself stuck, I have to write an application (which for example would call the METHOD_IN_DIRECT function that I defined in a switch case in my IoDeviceControl)

I therefore tried to start from an example on github and modified it so that it works ... but obviously as this example is for a NONpnp driver it is not usable for my driver which is pnp.

So I looked for examples of applications that worked with a pnp driver to see the model / shape, but I can't find a tutorial / sites / example on the realization of this famous application, one of the only sites that spoke about it was saying:

"Set an interface guide so the application can find the device and talk to it."

now my question is:

"how to write an aplication to control a PNP driver"

the main in "test.c":

int __cdecl
main(
    _In_              ULONG argc,
    _In_reads_(argc) PCHAR argv[]
    )
{
    HANDLE   hDevice;
    DWORD    errNum = 0;
    CHAR     driverLocation[MAX_PATH];
    BOOL     ok;
    LONG     error;
//    ULONG bytesReturned;

    printf("main start. \n");


    // 
    //open the device
    printf("createFile. \n");
    
    hDevice = CreateFileA(DRIVER_NAME,
                        GENERIC_READ | GENERIC_WRITE,
                        0,
                        NULL,
                        CREATE_ALWAYS,
                        FILE_ATTRIBUTE_NORMAL,
                        NULL);


    if (hDevice == INVALID_HANDLE_VALUE){...}
    
    printf("press enter \n");

    int c = getchar();

    printf("reception d'un charactere . \n");

    if (c) {
        
        printf("ioctl go \n");

        DoIoctls(hDevice);

        printf("ioctl end \n");

        //
        // Close the handle to the device before unloading the driver.
        //
        CloseHandle(hDevice);

        //
        // Unload the driver.  Ignore any errors.
        //
        ManageDriver(DRIVER_NAME, driverLocation, DRIVER_FUNC_REMOVE);
    }
    c = getchar();

    return;


}

here is the main of "test.c" which is at the base for nonpnp but that I modified that said I do not know how to embed the use of the GUID in my application (I imagine that it is because of that that it does not work).

the function DoIoctl :

VOID
DoIoctls(
    HANDLE hDevice
)
{
    char OutputBuffer[100];
    char InputBuffer[200];
    BOOL bRc;
    ULONG bytesReturned;


    //
    // Printing Input & Output buffer pointers and size
    //

    printf("\nInputBuffer Pointer = %p, BufLength = %Id\n", InputBuffer,sizeof(InputBuffer));
        
    printf("OutputBuffer Pointer = %p BufLength = %Id\n", OutputBuffer,sizeof(OutputBuffer));
        

    //
    // Performing METHOD_IN_DIRECT
    //

    printf("\nCalling DeviceIoControl METHOD_IN_DIRECT\n");

    if (FAILED(StringCchCopy(InputBuffer, sizeof(InputBuffer),"this String is from User Application; using METHOD_IN_DIRECT"))) 
    {
        return;
    }

    if (FAILED(StringCchCopy(OutputBuffer, sizeof(OutputBuffer),"This String is from User Application in OutBuffer; using METHOD_IN_DIRECT"))) 
    {
        return;
    }

    bRc = DeviceIoControl(hDevice,
                        (DWORD)Spw_PCIe_IOCTL_IN_BUFFERED,
                        InputBuffer,
                        (DWORD)strlen(InputBuffer) + 1,
                        OutputBuffer,
                        sizeof(OutputBuffer),
                        &bytesReturned,
                        NULL
                        );

    if (!bRc)
    {
        printf("Error in DeviceIoControl : %d \n", GetLastError());
        return;
    }

    printf("    Number of bytes transfered from OutBuffer: %d\n",bytesReturned);    


    //
    // Performing METHOD_OUT_DIRECT
    //

    printf("\nCalling DeviceIoControl METHOD_OUT_DIRECT\n");
    if (FAILED(StringCchCopy(InputBuffer, sizeof(InputBuffer), "this String is from User Application; using METHOD_OUT_DIRECT"))) {
        return;
    }

    memset(OutputBuffer, 0, sizeof(OutputBuffer));

    bRc = DeviceIoControl(hDevice,
                        (DWORD)Spw_PCIe_IOCTL_OUT_BUFFERED,
                        InputBuffer,
                        (DWORD)strlen(InputBuffer) + 1,
                        OutputBuffer,
                        sizeof(OutputBuffer),
                        &bytesReturned,
                        NULL
                        );

    if (!bRc)
    {
        printf("Error in DeviceIoControl : : %d", GetLastError());
        return;
    }

    printf("    OutBuffer (%d): %s\n", bytesReturned, OutputBuffer);

    return;
}

function ManageDriver :

BOOLEAN
ManageDriver(                                //   <- ManageDriver 
    IN LPCTSTR  DriverName,
    IN LPCTSTR  ServiceName,
    IN USHORT   Function
)
{

    SC_HANDLE   schSCManager;
    BOOLEAN rCode = TRUE;

    schSCManager = OpenSCManager(NULL,                   // local machine
                                 NULL,                   // local database
                                 SC_MANAGER_ALL_ACCESS   // access required
                                 )   

    // Do the requested function.
    switch (Function) {;

    case DRIVER_FUNC_REMOVE:       //  REMOVE

        printf("remove case. \n");
        // Stop the driver.

        StopDriver(schSCManager,DriverName);
            
        // Remove the driver service.

        RemoveDriver(schSCManager,DriverName);

        // Ignore all errors.

        rCode = TRUE;

        break;

    default:
        printf("Unknown ManageDriver() function. \n");
        rCode = FALSE;

        break;

     }


    // Close handle to service control manager.
    if (schSCManager) {

        CloseServiceHandle(schSCManager);
    }


    return rCode;
}   // ManageDriver  fin 

function remove :

BOOLEAN
RemoveDriver(                                 //   <- RemoveDriver
    _In_ SC_HANDLE    SchSCManager,
    _In_ LPCTSTR      DriverName
)
{
    SC_HANDLE   schService;
    BOOLEAN     rCode;


    // Open the handle to the existing service.

    schService = OpenService(SchSCManager,DriverName,SERVICE_ALL_ACCESS);

    // Mark the service for deletion from the service control manager database.

    DeleteService(schService)

if (schService) {

        CloseServiceHandle(schService);
    }

    return rCode;

}   // RemoveDriver  fin 

function StartDriver :

BOOLEAN
StartDriver(
    _In_ SC_HANDLE    SchSCManager,
    _In_ LPCTSTR      DriverName
)
{
    SC_HANDLE   schService;
    DWORD       err;


    // Open the handle to the existing service.

    schService = OpenService(SchSCManager, DriverName,SERVICE_ALL_ACCESS );
       
    // Start the execution of the service (i.e. start the driver).

    StartService(schService,     // service identifier
                      0,              // number of arguments
                      NULL            // pointer to arguments
                      )


    // Close the service object.

    if (schService) {

        CloseServiceHandle(schService);
    }

    return TRUE;

}   // StartDriver   fin

function StopDriver :

BOOLEAN
StopDriver(
    _In_ SC_HANDLE    SchSCManager,
    _In_ LPCTSTR      DriverName
)
{
    BOOLEAN         rCode = TRUE;
    SC_HANDLE       schService;
    SERVICE_STATUS  serviceStatus;

    //
    // Open the handle to the existing service.
    //

    schService = OpenService(SchSCManager,
                 DriverName,
                 SERVICE_ALL_ACCESS
                 );

    //
    // Request that the service stop.
    //

    ControlService(schService,
                   SERVICE_CONTROL_STOP,
                   &serviceStatus
                   )

    //
    // Close the service object.
    //

    if (schService) {

        CloseServiceHandle(schService);
    }

    return rCode;

}   //  StopDriver   fin


I deleted everything that is debugger otherwise there is sure that it would not be clear

if you had any indication maybe I'm wrong about the nature of applications maybe the solution is very dumb but if you know anything about writing application for pnp driver I'm a taker

to shorten it :

i would need an application skeleton, but not just any, i need one that works for a pnp driver.

(it doesn't matter which driver as long as it's a pnp) this is to be able to compare with my application and see what is missing from my aplication to support plug and play

cordially thank you all

pcie_driver
  • 1
  • 1
  • 5
  • It's not at all clear what your question is. – Luke Jun 02 '21 at 17:08
  • No, I don't understand what you're asking. And judging by the response to your question, neither does anybody else. Help us help you by clarifying what you are trying to do. – Luke Jun 03 '21 at 09:20
  • i edit the question, it's better ? – pcie_driver Jun 03 '21 at 10:21
  • It's still confusing, but are you just trying to communicate with the driver from user mode? It sounds similar to [this question](https://stackoverflow.com/questions/38966019/kmdf-ioctl-communication-with-nonpnp-driver). In that case, it's just a simple call to `DeviceIoControl()` and corresponding implementation of `DRIVER_DISPATCH`. I don't think PNP or KMDF are relevant, other than KMDF having some kind of wrapper around `DRIVER_DISPATCH`. – Luke Jun 03 '21 at 13:36
  • what I want is to write a program that allows me to tell my pilot what to do, have an .exe that allows me to make my pilot do things – pcie_driver Jun 03 '21 at 14:09
  • Oh, I think I see what you're getting at. It's just using standard IOCTLs to the device opened via `CreateFile()`, but you need to get the device path using the `SetupDi` functions. See the [answer here](https://stackoverflow.com/questions/67527315/can-i-use-setupdienumdeviceinterfaces-to-get-a-devicepath-from-setupdigetdevicei). – Luke Jun 03 '21 at 14:48
  • wow its this ! thank you I don't know if with that I could do ... how to tell this? the application which comes to call the ioctl and creatfile? so I keep the topic open in case of example of link between the driver and the "application" via the guid ! – pcie_driver Jun 03 '21 at 15:13

1 Answers1

0

You need to obtain the device path using the SetupDi functions as shown in this answer.

Luke
  • 11,211
  • 2
  • 27
  • 38