阅读:2183回复:4
关于用deviceiocontrol实现应用程序与驱动的通信问题(蓝屏)?
这是动态加载驱动程序的例子修改的。
我刚学驱动,希望个位大虾帮帮忙。 驱动程序: #include <ntddk.h> #define IOCTL_SET_FILTER \\ CTL_CODE(0x8000, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) #define NT_DEVICE_NAME L\"\\\\Device\\\\Twdm1\" #define DOS_DEVICE_NAME L\"\\\\DosDevices\\\\Twdm1\" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp); NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp); NTSTATUS DispatchControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); VOID GpdUnload(PDRIVER_OBJECT DriverObject); NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info); ////////////////////// PDEVICE_OBJECT fdo; BOOLEAN fSymbolicLink; NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { //UNREFERENCED_PARAMETER (RegistryPath); NTSTATUS status; UNICODE_STRING ntDeviceName; UNICODE_STRING win32DeviceName; DbgPrint( \"TWDM: DriverEntry for Twdm.sys ...... \\n\" ); fSymbolicLink = FALSE; // // Create dispatch points for the IRPs. // DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl; DriverObject->DriverUnload = GpdUnload; //DriverObject->MajorFunction[IRP_MJ_PNP] = GpdDispatchPnp; //DriverObject->MajorFunction[IRP_MJ_POWER] = GpdDispatchPower; //DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = GpdDispatchSystemControl; //DriverObject->DriverExtension->AddDevice = GpdAddDevice; RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); status = IoCreateDevice(DriverObject, 0, &ntDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &fdo); if (!NT_SUCCESS (status)) { DbgPrint( \"TWDM: IoCreateDevice() faild ! \\n\" ); } else { DbgPrint( \"TWDM: IoCreateDevice() ok ! \\n\" ); RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); status = IoCreateSymbolicLink( &win32DeviceName, &ntDeviceName ); if (!NT_SUCCESS(status)) { DbgPrint( \"TWDM: IoCreateSymbolicLink() faild ! \\n\" ); } else { DbgPrint( \"TWDM: IoCreateSymbolicLink() ok ! \\n\" ); fSymbolicLink = TRUE; } fdo->Flags &= ~DO_DEVICE_INITIALIZING; } if (!NT_SUCCESS(status)) { if(fdo) { IoDeleteDevice(fdo); } if(fSymbolicLink) { IoDeleteSymbolicLink(&win32DeviceName); } } return status; } NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp) { unsigned long info; unsigned long cbin; unsigned long cbout; unsigned long code; PDEVICE_EXTENSION pdx; PIO_STACK_LOCATION stack; NTSTATUS status; // DispatchControl pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); info = 0; stack = IoGetCurrentIrpStackLocation(Irp); cbin = stack->Parameters.DeviceIoControl.InputBufferLength; cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; code = stack->Parameters.DeviceIoControl.IoControlCode; switch (code) { // process request case IOCTL_SET_FILTER: break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } // process request IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return CompleteRequest(Irp, status, info); } NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info) { // CompleteRequest Irp->IoStatus.Status = status; Irp->IoStatus.Information = info; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // CompleteRequest // DispatchControl NTSTATUS DispatchCreate(PDEVICE_OBJECT fdo, PIRP Irp) { NTSTATUS status; DbgPrint( \"TWDM: IRP_MJ_CREATE for Twdm.sys ...... \\n\" ); status = STATUS_SUCCESS; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } // DispatchCreate NTSTATUS DispatchClose(PDEVICE_OBJECT fdo, PIRP Irp) { // DispatchClose NTSTATUS status; DbgPrint( \"TWDM: IRP_MJ_CLOSE for Twdm.sys ...... \\n\" ); status = STATUS_SUCCESS; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } // DispatchClose VOID GpdUnload(PDRIVER_OBJECT DriverObject) { UNICODE_STRING win32DeviceName; DbgPrint( \"TWDM: GpdUnload() for Twdm.sys ...... \\n\" ); RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); if(fdo) { IoDeleteDevice(fdo); } if(fSymbolicLink) { IoDeleteSymbolicLink(&win32DeviceName); } } 应用程序: #include \"stdafx.h\" #include <windows.h> #include <winsvc.h> #include <conio.h> #include <devioctl.h> void DelSvr( char * ); #define IOCTL_SET_FILTER \\ CTL_CODE(0x8000, 801, METHOD_BUFFERED, FILE_ANY_ACCESS) int main(int argc, char* argv[]) { HANDLE hWdm; printf(\"Hello World!\\n\"); SC_HANDLE hServiceMgr, hServiceTwdm; BOOL bRtn; DWORD dwRtn, dwSize = 256; char szDir[256]; if( argc > 1 ) { DelSvr( \"Twdm1\" ); return 0; } GetCurrentDirectory( dwSize, szDir ); strcat( szDir, \"\\\\Twdm.sys\" ); LPCTSTR lpszBinaryPathName = TEXT(szDir); hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { printf( \"OpenSCManager() Faild %d ! \\n\", GetLastError() ); return 0; } else { printf( \"OpenSCManager() ok ! \\n\" ); } hServiceTwdm = CreateService( hServiceMgr, TEXT(\"Twdm1\"), TEXT(\"Twdm1\"), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, lpszBinaryPathName, NULL, NULL, NULL, NULL, NULL); if( hServiceTwdm == NULL ) { dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS ) { CloseServiceHandle( hServiceMgr ); printf( \"CrateService() Faild %d ! \\n\", dwRtn ); return 0; } else { printf( \"CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \\n\" ); } hServiceTwdm = OpenService( hServiceMgr, TEXT(\"Twdm1\"), SERVICE_ALL_ACCESS ); if( hServiceTwdm == NULL ) { dwRtn = GetLastError(); CloseServiceHandle( hServiceMgr ); printf( \"OpenService() Faild %d ! \\n\", dwRtn ); return 0; } else { printf( \"OpenService() ok ! \\n\" ); } } else { printf( \"CrateService() ok ! \\n\" ); } bRtn = StartService( hServiceTwdm, NULL, NULL ); if( !bRtn ) { //ERROR_PATH_NOT_FOUND dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING ) { printf( \"StartService() Faild %d ! \\n\", dwRtn ); CloseServiceHandle( hServiceTwdm ); CloseServiceHandle( hServiceMgr ); return 0; } else { if( dwRtn != ERROR_IO_PENDING ) { printf( \"StartService() Faild ERROR_IO_PENDING ! \\n\"); } else { printf( \"StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \\n\"); } } } hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if( hWdm != INVALID_HANDLE_VALUE ) { //每调用这里的时候会蓝屏。 char m_dwOptions[10]; DWORD bytesWrite; m_dwOptions[0] = \'a\'; m_dwOptions[1] = \'b\'; m_dwOptions[2] = \'c\'; m_dwOptions[3] = \'d\'; m_dwOptions[4] = \'e\'; printf( \"Open Driver Twdm ok ! \\n\" ); if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) { printf( \"IOCTL_SET_FILTER ! \\n\" ); } else { printf( \"IOCTL_SET_FILTER erro \\n\" ); } } else { printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() ); } CloseHandle( hWdm ); CloseServiceHandle( hServiceTwdm ); CloseServiceHandle( hServiceMgr ); printf( \"按任意键 卸载驱动程序 !\\n\" ); getch(); DelSvr( \"Twdm1\" ); return 0; } void DelSvr( char * szSvrName ) { SC_HANDLE hServiceMgr, hServiceTwdm; SERVICE_STATUS SvrSta; hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { printf( \"DelSvr::OpenSCManager() Faild %d ! \\n\", GetLastError() ); return; } else { printf( \"DelSvr::OpenSCManager() ok ! \\n\" ); } hServiceTwdm = OpenService( hServiceMgr, TEXT(szSvrName), SERVICE_ALL_ACCESS ); if( hServiceTwdm == NULL ) { CloseServiceHandle( hServiceMgr ); printf( \"DelSvr::OpenService() Faild %d ! \\n\", GetLastError() ); return; } else { printf( \"DelSvr::OpenService() ok ! \\n\" ); } if( !ControlService( hServiceTwdm, SERVICE_CONTROL_STOP , &SvrSta ) ) { printf( \"DelSvr::ControlService() Faild %d !\\n\", GetLastError() ); } else { printf( \"DelSvr::ControlService() ok !\\n\" ); } if( !DeleteService( hServiceTwdm ) ) { printf( \"DelSvr::DeleteSrevice() Faild %d !\\n\", GetLastError() ); } else { printf( \"DelSvr::DeleteSrevice() ok !\\n\" ); } CloseServiceHandle( hServiceTwdm ); CloseServiceHandle( hServiceMgr ); return; } |
|
|
沙发#
发布于:2002-12-25 09:48
DeviceExtension没有初始化,
把下面几行去掉: pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); info = 0; ... IoReleaseRemoveLock(&pdx->RemoveLock, Irp); |
|
板凳#
发布于:2002-12-25 22:30
谢谢,现在不会蓝屏了,但是现在又出现了一点问题,
那就是应用程序与驱动程序发几个信息之后便不可以在发了。 错误代码是 1061(服务无法在此时接受控制信息。) 这个时候该驱动也无法用 NET STOP Twdm1 关闭,必须重新启动电脑才可以再发控制信息。 ////应用程序: hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); if( hWdm != INVALID_HANDLE_VALUE ) { char m_dwOptions[10]; DWORD bytesWrite; m_dwOptions[0] = \'a\'; m_dwOptions[1] = \'b\'; m_dwOptions[2] = \'c\'; m_dwOptions[3] = \'d\'; m_dwOptions[4] = \'e\'; printf( \"Open Driver Twdm ok ! \\n\" ); if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) { printf( \"IOCTL_SET_FILTER ! \\n\" ); } else { printf( \"IOCTL_SET_FILTER erro \\n\" ); } } else { printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() ); } CloseHandle( hWdm ); |
|
|
地板#
发布于:2002-12-26 12:30
DeleteService执行后一般需要重启,所以CreateService后,以后不用再调用CreateService和DeleteService,否则会返回io重叠错误。
另外,CreateFile不能使用FILE_FLAG_OVERLAPPED标志,参数必须如下: GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL |
|
地下室#
发布于:2002-12-31 13:21
////应用程序已经改为(set.exe):
在基于对话框应用中: void OnClickSetData() { HANDLE hWdm = CreateFile(\"\\\\\\\\.\\\\Twdm1\", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if( hWdm != INVALID_HANDLE_VALUE ) { char m_dwOptions[10]; DWORD bytesWrite; m_dwOptions[0] = \'a\'; m_dwOptions[1] = \'b\'; m_dwOptions[2] = \'c\'; m_dwOptions[3] = \'d\'; m_dwOptions[4] = \'e\'; printf( \"Open Driver Twdm ok ! \\n\" ); if( DeviceIoControl(hWdm ,IOCTL_SET_FILTER, ( char * )m_dwOptions, 10, ( char * )m_dwOptions, 10, &bytesWrite, NULL ) ) { printf( \"IOCTL_SET_FILTER ! \\n\" ); } else { printf( \"IOCTL_SET_FILTER erro \\n\" ); } } else { printf( \"Open Driver Twdm faild %d ! \\n\", GetLastError() ); } CloseHandle( hWdm ); } } 我用DriverStudio的Driver monitor加载它后,再用上面的应用程序(set.exe) 对它控制,发现虽然应用程序窗口关闭了,但是在按CTRL+ALT+DEL时set.exe 居然还在进程列表中。我猜这就是导致 错误代码 1061(服务无法在此时接受控制信息。)的原因。不知应该怎么样解决?另外,我想在驱动中传递字符串“HELLO WORLD”给 应用程序,驱动程序和应用程序应该改那些地方? [编辑 - 12/31/02 by wangwolue1] |
|
|