如何编写应用程序来控制 pnp 和 kmdf 中的驱动程序?

问题描述

所以我会详细说明以便大家​​容易理解

我必须为 pcie 卡制作一个驱动程序,我已经有了我在 kmdf 中编写的驱动程序,现在我正在使用这个驱动程序,不幸的是我发现自己卡住了,我必须编写一个应用程序(例如会调用我在 IoDeviceControl 的开关盒中定义的 METHOD_IN_DIRECT 函数)

因此,我尝试从 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,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,(DWORD)strlen(InputBuffer) + 1,&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,"this String is from User Application; using METHOD_OUT_DIRECT"))) {
        return;
    }

    memset(OutputBuffer,sizeof(OutputBuffer));

    bRc = DeviceIoControl(hDevice,(DWORD)Spw_PCIe_IOCTL_OUT_BUFFERED,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 

函数启动驱动程序:

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


    // Open the handle to the existing service.

    schService = OpenService(SchSCManager,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,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,哪个驱动都无所谓) 这是为了能够与我的应用程序进行比较,看看我的应用程序缺少什么以支持即插即用

衷心感谢大家

解决方法

您需要使用 this answer 中所示的 SetupDi 函数获取设备路径。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...