阅读:4132回复:1
为什么我程序里的DeviceIoControl总是返回错误码87?
最近开始学习编写驱动,刚输入了一个示例,在DriverMonitor中成功加载并正确产生一个符号链接,但是我用一个exe文件调用驱动时,总是有提示说DeviceIoControl执行出错,错误代码是87,表示传输给此函数的参数有问题,但是我一直不知道是什么参数有问题呢?请各路高手赐教呀。感激!!
/////驱动代码 #include <ntddk.h> #define DEVICE_HELLO_INDEX 0x860 #define START_HELLOWORLD (ULONG) CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) #define STOP_HELLOWORLD (ULONG) CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX + 1, METHOD_BUFFERED, FILE_ANY_ACCESS) const WCHAR ntDeviceName[] = L"\\Device\\HelloWorld"; const WCHAR dosDeviceName[] = L"\\DosDevices\\HelloWorld"; NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp); VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject); PDEVICE_OBJECT IpDeviceObject = NULL; //全局变量 //驱动入口 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus = STATUS_SUCCESS; UNICODE_STRING DeviceNameString; UNICODE_STRING DeviceLinkString; DbgPrint("Hi,Starting DriverEntry()\n"); RtlInitUnicodeString(&DeviceNameString, ntDeviceName); RtlInitUnicodeString(&DeviceLinkString, dosDeviceName); ntStatus = IoCreateDevice(DriverObject, 0, &DeviceNameString, FILE_DEVICE_UNKNOWN, 0, TRUE, &IpDeviceObject); if (!NT_SUCCESS(ntStatus)) { DbgPrint("Hi, Error IoCreateDevice()\n"); return STATUS_UNSUCCESSFUL; } ntStatus = IoCreateSymbolicLink(&DeviceLinkString, &DeviceNameString); if (!NT_SUCCESS(ntStatus)) { DbgPrint("Hi, Error IoCreateDevice()\n"); return STATUS_UNSUCCESSFUL; } DriverObject->MajorFunction[IRP_MJ_CREATE] = HelloWorldDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloWorldDispatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloWorldDispatch; DriverObject->DriverUnload = HelloWorldUnload; DbgPrint("Hi, DriverEntry() finished.\n"); return ntStatus; } NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObjet, IN PIRP pIrp) { NTSTATUS ntStatus = STATUS_SUCCESS; ULONG IoControlCodes = 0; PIO_STACK_LOCATION IrpStack = NULL; pIrp->IoStatus.Status = STATUS_SUCCESS; pIrp->IoStatus.Information = 0; DbgPrint("Hi, starting HelleWorldDispatch()\n"); IrpStack = IoGetCurrentIrpStackLocation(pIrp); switch(IrpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("hi, IRP_MJ_CREATE\n"); break; case IRP_MJ_CLOSE: DbgPrint("hi, IRP_MJ_CLOSE\n"); break; case IRP_MJ_DEVICE_CONTROL: DbgPrint("hi, IRP_MJ_DEVICE_CONTROL\n"); switch(IoControlCodes) { case START_HELLOWORLD: DbgPrint("hi, Starting \"Hello World\"\n"); break; case STOP_HELLOWORLD: DbgPrint("hi, Stoping \"Hello World\"\n"); break; default: pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER; break; } break; default: break; } ntStatus = pIrp->IoStatus.Status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus; } VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceLinkString; PDEVICE_OBJECT DeviceObjectTemp1 = NULL; PDEVICE_OBJECT DeviceObjectTemp2 = NULL; DbgPrint("hi, Starting HelloWorldUnload()\n"); RtlInitUnicodeString(&DeviceLinkString, dosDeviceName); IoDeleteSymbolicLink(&DeviceLinkString); if (DriverObject) { DeviceObjectTemp1 = DriverObject->DeviceObject; while (DeviceObjectTemp1) { DeviceObjectTemp2 = DeviceObjectTemp1; DeviceObjectTemp1 = DeviceObjectTemp1->NextDevice; IoDeleteDevice(DeviceObjectTemp2); } } } /////测试代码 #include <windows.h> #include <winioctl.h> #include <stdio.h> #define DEVICE_HELLO_INDEX 0x860 #define START_HELLOWORLD (ULONG) CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) #define STOP_HELLOWORLD (ULONG) CTL_CODE(FILE_DEVICE_UNKNOWN, DEVICE_HELLO_INDEX + 1, METHOD_BUFFERED, FILE_ANY_ACCESS) #define erron GetLastError() #define MY_DEVICE_NAME "\\\\.\\HelloWorld" #define MY_DEVICE_START "-start" #define MY_DEVICE_STOP "-stop" BOOL DriverControl(TCHAR* Maik); VOID Usage(TCHAR* Parameter); DWORD BLACK = 0; int main(int argc, TCHAR* argv[]) { if (argc != 2) { Usage(argv[0]); return 0; } if (strcmp(argv[1], MY_DEVICE_START) == 0 || strcmp(argv[1], MY_DEVICE_STOP) == 0) { DriverControl(argv[1]); } else { Usage(argv[0]); return 0; } return 0; } BOOL DriverControl(TCHAR * Maik) { HANDLE hDevice = NULL; DWORD RetBytes = 0; hDevice = CreateFile(MY_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == INVALID_HANDLE_VALUE) { printf("CreteFile() GetLastError reports %d\n", erron); return FALSE; } if (strcmpi(Maik, MY_DEVICE_START) == 0) { if (FALSE == (DeviceIoControl(hDevice, START_HELLOWORLD, &BLACK, sizeof(BLACK), NULL, 0, &RetBytes, NULL))) { printf("DeviceIoControl() GetLastError reports %d\n", erron); CloseHandle(hDevice); return FALSE; } else { printf("start success!\n"); } } if (strcmpi(Maik, MY_DEVICE_STOP) == 0) { if (!(DeviceIoControl(hDevice, STOP_HELLOWORLD, &BLACK, sizeof(BLACK), NULL, 0, &RetBytes, NULL))) { printf("DeviceIoControl() GetLastError reports %d\n", erron); CloseHandle(hDevice); return FALSE; } else { printf("stop success!\n"); } } if (hDevice) { CloseHandle(hDevice); } return TRUE; } void Usage(TCHAR* Parameter) { fprintf(stderr, "===============================================\n \ %s -start\t启动\n \ %s -stop \t停止\n \ ===============================================\n", Parameter, Parameter); } |
|
沙发#
发布于:2008-10-23 10:11
不返回87才怪,
因为你结束IRP的时候就是返回这个错, 之所以返回这个错,是因为你的IoControlCodes = 0,在switch那个地方永远跳到出错的case,实际上IoControlCode应该从IrpStack 里面取。 好好看看IRP_MJ_DEVICE_CONTROL的说明。 |
|