Как написать приложение для управления драйвером, который в pnp и в kmdf?

поэтому я подробно расскажу, чтобы мы могли легко понять

Мне нужно сделать драйвер для карты pcie, у меня уже есть драйвер, который я написал в kmdf, сейчас я использую этот драйвер, к сожалению, я застрял, я должен написать приложение (которое например вызовет функцию METHOD_IN_DIRECT который я определил в случае переключения в моем IoDeviceControl)

Поэтому я попытался начать с примера на github и изменил его так, чтобы он работал... но, очевидно, поскольку этот пример предназначен для драйвера NONpnp, его нельзя использовать для моего драйвера pnp.

Итак, я искал примеры приложений, которые работали с pnp-драйвером, чтобы увидеть модель/шейп, но не могу найти туториал/сайты/пример по реализации этого знаменитого приложения, один из единственных сайтов, который говорил об этом, был говоря:

Настройте руководство по интерфейсу, чтобы приложение могло найти устройство и взаимодействовать с ним.

теперь мой вопрос:

как написать приложение для управления драйвером PNP

главное в 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;


}

вот основная часть test.c, которая лежит в основе для nonpnp, но которую я изменил, сказав, что я не знаю, как внедрить использование GUID в свое приложение (я предполагаю, что это из-за этого, что он не работает ).

функция 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;
}

функция «Управление драйверами»:

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 

функция удаления:

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 

функция 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

функция СтопДрайвер:

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


Я удалил все что есть отладчиком иначе там точно не понятно будет

если у вас есть какие-либо указания, может быть, я ошибаюсь насчет природы приложений, может быть, решение очень глупое, но если вы знаете что-нибудь о написании приложения для драйвера pnp, я принимаю

чтобы сократить его:

мне нужен скелет приложения, но не любой, мне нужен тот, который работает с драйвером pnp.

(неважно, какой драйвер, если это pnp) это нужно для того, чтобы иметь возможность сравнить с моим приложением и посмотреть, чего не хватает в моем приложении для поддержки plug and play

сердечно благодарю вас всех


person pcie_driver    schedule 02.06.2021    source источник
comment
Совершенно не понятно, о чем ваш вопрос.   -  person Luke    schedule 02.06.2021
comment
Нет, я не понимаю, о чем ты спрашиваешь. И, судя по ответу на ваш вопрос, никто другой тоже. Помогите нам помочь вам, уточнив, что вы пытаетесь сделать.   -  person Luke    schedule 03.06.2021
comment
я редактирую вопрос, это лучше?   -  person pcie_driver    schedule 03.06.2021
comment
Это все еще сбивает с толку, но вы просто пытаетесь общаться с драйвером из пользовательского режима? Это похоже на этот вопрос. В этом случае это просто вызов DeviceIoControl() и соответствующая реализация DRIVER_DISPATCH. Я не думаю, что PNP или KMDF имеют значение, за исключением того, что KMDF имеет какую-то оболочку вокруг DRIVER_DISPATCH.   -  person Luke    schedule 03.06.2021
comment
что я хочу, так это написать программу, которая позволяет мне говорить моему пилоту, что делать, иметь .exe, который позволяет мне заставить моего пилота делать что-то   -  person pcie_driver    schedule 03.06.2021
comment
О, кажется, я понимаю, к чему ты клонишь. Это просто использование стандартных IOCTL для устройства, открытого через CreateFile(), но вам нужно получить путь к устройству с помощью функций SetupDi. См. ответ здесь.   -  person Luke    schedule 03.06.2021
comment
вау это! спасибо, я не знаю, смогу ли я это сделать ... как это сказать? приложение, которое вызывает ioctl и creatfile? поэтому я держу тему открытой на случай примера связи между драйвером и приложением через guid!   -  person pcie_driver    schedule 03.06.2021


Ответы (1)


Вам необходимо получить путь к устройству с помощью функций SetupDi, как показано в этот ответ.

person Luke    schedule 03.06.2021