阅读:1490回复:3
znsoft老大请再帮帮忙!帮我看看写文件的失败代码
方法一、使用ZwWriteFile
我在read或write中调用ZwWriteFile为什么总是失败?这个函数没几个参数啊,应该不会错吧,是不是还是重入问题?谢谢!!! TempBuffer = ExAllocatePool(NonPagedPool, 100); for(i = 0; i<100; i++) { ((PUCHAR) TempBuffer) = '9'; }//自己随便弄一个Buffer来写进去 RtlInitUnicodeString(&ObjectName, L"\\Device\\MyDeviceD\\temp.txt"); //MyDeviceD是自己定义的shadow device object,防止Create重入 InitializeObjectAttributes(&ObjectAttributes, &ObjectName, OBJ_KERNEL_HANDLE, NULL, NULL ); Status = ZwCreateFile(&FileHandle, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, 0, NULL, 0 );//Create是成功的 if (!NT_SUCCESS(Status)) { return Status; } Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatus, TempBuffer, 100, NULL, NULL );//write不知道怎么,就是fail ZwClose(FileHandle); ExFreePool(TempBuffer); if (!NT_SUCCESS(Status)) { return Status; } |
|
沙发#
发布于:2005-07-01 11:27
michaelgz,谢谢指点,但是我将该函数放到system worker thread中还是写不进去内容,为什么?请看看代码,谢谢!
在write中: MyworkContext.FilterDeviceObject = DeviceObject; MyworkContext.Irp = Irp; KeInitializeEvent(&MyworkContext.Event, NotificationEvent, FALSE); ExInitializeWorkItem(&MyWorkItem, sfWriteToFile, &MyworkContext); ExQueueWorkItem(&MyWorkItem, DelayedWorkQueue); KeWaitForSingleObject(&MyworkContext.Event, Executive, KernelMode, FALSE, NULL); sfWriteToFile函数: VOID sfWriteToFile( IN OUT PWRITE_WORKER_CONTEXT WorkContext ) { HANDLE FileHandle; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; UNICODE_STRING ObjectName; PIRP Irp = WorkContext->Irp; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PVOID OldBuffer = NULL; ULONG Length = 0; RtlInitUnicodeString(&ObjectName, L"\\Device\\MyDeviceD\\temp.txt"); InitializeObjectAttributes(&ObjectAttributes, &ObjectName, OBJ_KERNEL_HANDLE, NULL, NULL ); Status = ZwCreateFile(&FileHandle, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, 0, NULL, 0 ); if (!NT_SUCCESS(Status)) { KeSetEvent(&(WorkContext->Event), IO_NO_INCREMENT, FALSE); return; } if (Irp->MdlAddress) OldBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress); else OldBuffer = Irp->UserBuffer; Length = IrpSp->Parameters.Write.Length; Status = ZwWriteFile(FileHandle, NULL, NULL, NULL, &IoStatus, OldBuffer, Length, NULL, NULL ); ZwClose(FileHandle); KeSetEvent(&(WorkContext->Event), IO_NO_INCREMENT, FALSE); return; } |
|
板凳#
发布于:2005-07-01 05:15
Callers of ZwWriteFile must be running at IRQL = PASSIVE_LEVEL and with APCs enabled.
IRP_MJ_WRITE/READ dispatch routines are not guaranteed running at PASSIVE_LEVEL. You should create file somewhere else. One possible solution is creating a workitem and do it in a working thread running at PASSIVE_LEVEL. |
|
地板#
发布于:2005-06-30 21:26
方法二、自己构造IRP发下去:
改用自己构造IRP的方法来写文件(在write dispatch routine中),代码如下,请帮忙看看: RtlInitUnicodeString(&ObjectName, L"\\Device\\MyDeviceD\\temp.txt"); InitializeObjectAttributes(&ObjectAttributes, &ObjectName, OBJ_KERNEL_HANDLE, NULL, NULL ); Status = ZwCreateFile(&FileHandle, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatus, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN_IF, 0, NULL, 0 ); if (!NT_SUCCESS(Status)));//Create是成功的 { return Status; } KeInitializeEvent(&WriteEvent, NotificationEvent, FALSE); WriteIrp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DevExt->FileSystemDeviceObject, OldBuffer,//从IRP中获得的buffer地址 Length,//从IRP中获得的数据长度 NULL, &WriteEvent, &IoStatus);//这里总是重启 if(WriteIrp == NULL) { ZwClose(FileHandle); return Status; } Status = ObReferenceObjectByHandle(FileHandle, 0, NULL, KernelMode, WriteFileObject, NULL); WriteIrp->RequestorMode = ExGetPreviousMode(); WriteIrp->Tail.Overlay.OriginalFileObject = WriteFileObject; WriteStack = IoGetNextIrpStackLocation(WriteIrp); WriteStack->FileObject = WriteFileObject; Status = IoCallDriver(DevExt->FileSystemDeviceObject, WriteIrp); if (!NT_SUCCESS(Status)) { IoFreeIrp(WriteIrp); ZwClose(FileHandle); return Status; } KeWaitForSingleObject(&WriteEvent, Executive, KernelMode, FALSE, NULL); KeClearEvent(&WriteEvent); IoFreeIrp(WriteIrp); ZwClose(FileHandle); |
|