Kernel 中调用其它驱动程序的几种方法

来源:互联网 发布:朱炫热血知乎 编辑:程序博客网 时间:2024/05/21 06:38

1.ZwCreateFile

UNICODE_STRING DeviceName;RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDA" );OBJECT_ATTRIBUTES objectAttributes;InitializeObjectAttributes(&objectAttributes, &DeviceName,OBJ_CASE_INSENSITIVE, NULL, NULL );HANDLE hDevice;IO_STATUS_BLOCK status_block;ntStatus = ZwCreateFile(&hDevice,FILE_READ_ATTRIBUTES,&objectAttributes,&status_block,NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN_IF,NULL,NULL,0);


通过 符号链接查找设备对象

  

//初始化objectAttributes    OBJECT_ATTRIBUTES objectAttributes;    InitializeObjectAttributes(&objectAttributes,                            &DeviceSymbolicLinkName,                            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,                            NULL,                            NULL );    HANDLE hSymbolic;    ntStatus = ZwOpenSymbolicLinkObject(&hSymbolic,FILE_ALL_ACCESS,&objectAttributes);    UNICODE_STRING LinkTarget;    LinkTarget.Buffer = (PWSTR)ExAllocatePool(PagedPool,MAX_SIZE);    LinkTarget.Length = 0;    LinkTarget.MaximumLength = MAX_SIZE;    ULONG unicode_length;    ntStatus = ZwQuerySymbolicLinkObject(hSymbolic,&LinkTarget,&unicode_length);

2.IoBuildSynchronousFsdRequest


PDEVICE_OBJECT DeviceObject = NULL;PFILE_OBJECT FileObject = NULL;//得到设备对象句柄,计数器加1//如果是第一次调用IoGetDeviceObjectPointer,会打开设备,相当于调用ZwCreateFilentStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);KdPrint(("DriverB:FileObject:%x\n",FileObject));KdPrint(("DriverB:DeviceObject:%x\n",DeviceObject));if (!NT_SUCCESS(ntStatus)){KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));ntStatus = STATUS_UNSUCCESSFUL;// 完成IRPpIrp->IoStatus.Status = ntStatus;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("DriverB:Leave B HelloDDKRead\n"));return ntStatus;}KEVENT event;KeInitializeEvent(&event,NotificationEvent,FALSE);IO_STATUS_BLOCK status_block;LARGE_INTEGER offsert = RtlConvertLongToLargeInteger(0);//创建同步IRPPIRP pNewIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,DeviceObject,NULL,0,&offsert,&event,&status_block); KdPrint(("DriverB:pNewIrp:%x\n",pNewIrp));PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(pNewIrp);stack->FileObject = FileObject;//调用DriverA,会一直调用到DriverA的派遣函数NTSTATUS status = IoCallDriver(DeviceObject,pNewIrp);
3.IoAllocateIrp 自己分发IRP
PDEVICE_OBJECT DeviceObject = NULL;PFILE_OBJECT FileObject = NULL;//得到设备对象指针ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);KdPrint(("DriverB:FileObject:%x\n",FileObject));KdPrint(("DriverB:DeviceObject:%x\n",DeviceObject));if (!NT_SUCCESS(ntStatus)){KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));ntStatus = STATUS_UNSUCCESSFUL;// 完成IRPpIrp->IoStatus.Status = ntStatus;pIrp->IoStatus.Information = 0;// bytes xferedIoCompleteRequest( pIrp, IO_NO_INCREMENT );KdPrint(("DriverB:Leave B HelloDDKRead\n"));return ntStatus;}KEVENT event;KeInitializeEvent(&event,NotificationEvent,FALSE);PIRP pNewIrp = IoAllocateIrp(DeviceObject->StackSize,FALSE);KdPrint(("pNewIrp->UserEvent :%x\n",pNewIrp->UserEvent));pNewIrp->UserEvent = &event;IO_STATUS_BLOCK status_block;    pNewIrp->UserIosb = &status_block;    pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();//因为DriverA是BUFFER IO设备pNewIrp->AssociatedIrp.SystemBuffer = NULL; KdPrint(("DriverB:pNewIrp:%x\n",pNewIrp));PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(pNewIrp);stack->MajorFunction = IRP_MJ_READ;stack->MinorFunction=IRP_MN_NORMAL;//0stack->FileObject = FileObject;//调用DriverA驱动NTSTATUS status = IoCallDriver(DeviceObject,pNewIrp);    if (status == STATUS_PENDING) {       status = KeWaitForSingleObject(                            &event,                            Executive,                            KernelMode,                            FALSE, // Not alertableNULL);   KdPrint(("STATUS_PENDING\n"));    } ObDereferenceObject( FileObject );IoFreeIrp(pNewIrp);


  

原创粉丝点击