lydzyw
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分257分
  • 威望40点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
阅读:1489回复:3

znsoft老大请再帮帮忙!帮我看看写文件的失败代码

楼主#
更多 发布于:2005-06-30 21:23
  方法一、使用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;
           }
lydzyw
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分257分
  • 威望40点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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);
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
板凳#
发布于: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.
lydzyw
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分257分
  • 威望40点
  • 贡献值0点
  • 好评度28点
  • 原创分0分
  • 专家分0分
地板#
发布于: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;
}
游客

返回顶部