如何编写应用程序来控制 pnp 和 kmdf 驱动程序?
How to write an application to control a driver which is pnp and in kmdf?
所以我会详细的让大家容易理解
我必须为 pcie 卡制作一个驱动程序,我已经有了我在 kmdf 中编写的驱动程序,现在我正在使用这个驱动程序,不幸的是我发现自己卡住了,我必须编写一个应用程序(例如会调用我在 IoDeviceControl 的 switch case 中定义的 METHOD_IN_DIRECT 函数)
因此,我尝试从 github 上的一个示例开始,并对其进行了修改,使其可以正常工作……但很明显,因为这个示例是针对 NONpnp 驱动程序的,所以它不适用于我的 pnp 驱动程序。
所以我寻找与 pnp 驱动程序一起工作的应用程序示例以查看模型/形状,但我找不到关于实现这个著名应用程序的教程/站点/示例,这是唯一的站点之一谈到它的人说:
"Set an interface guide so the application can find the device and talk to it."
现在我的问题是:
"如何编写应用程序来控制 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
函数 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
我删除了所有调试器,否则肯定不清楚
如果您有任何迹象,也许我对应用程序的性质有误,也许解决方案非常愚蠢,但如果您知道有关为 pnp 驱动程序编写应用程序的任何信息,我就是接受者
缩短:
我需要一个应用程序框架,但不仅仅是任何一个,我需要一个适用于 pnp 驱动程序的框架。
(哪个驱动不重要,只要是pnp即可)
这是为了能够与我的应用程序进行比较,看看我的应用程序缺少什么来支持即插即用
衷心感谢大家
您需要使用SetupDi
函数获取设备路径,如所示。
所以我会详细的让大家容易理解
我必须为 pcie 卡制作一个驱动程序,我已经有了我在 kmdf 中编写的驱动程序,现在我正在使用这个驱动程序,不幸的是我发现自己卡住了,我必须编写一个应用程序(例如会调用我在 IoDeviceControl 的 switch case 中定义的 METHOD_IN_DIRECT 函数)
因此,我尝试从 github 上的一个示例开始,并对其进行了修改,使其可以正常工作……但很明显,因为这个示例是针对 NONpnp 驱动程序的,所以它不适用于我的 pnp 驱动程序。
所以我寻找与 pnp 驱动程序一起工作的应用程序示例以查看模型/形状,但我找不到关于实现这个著名应用程序的教程/站点/示例,这是唯一的站点之一谈到它的人说:
"Set an interface guide so the application can find the device and talk to it."
现在我的问题是:
"如何编写应用程序来控制 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
函数 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
我删除了所有调试器,否则肯定不清楚
如果您有任何迹象,也许我对应用程序的性质有误,也许解决方案非常愚蠢,但如果您知道有关为 pnp 驱动程序编写应用程序的任何信息,我就是接受者
缩短:
我需要一个应用程序框架,但不仅仅是任何一个,我需要一个适用于 pnp 驱动程序的框架。
(哪个驱动不重要,只要是pnp即可) 这是为了能够与我的应用程序进行比较,看看我的应用程序缺少什么来支持即插即用
衷心感谢大家
您需要使用SetupDi
函数获取设备路径,如