SecotrReadWrite

来源:互联网 发布:北京外国语大学网络 编辑:程序博客网 时间:2024/05/01 16:02
 NTSTATUS     SecotrReadWrite( PDEVICE_OBJECT pDeviceObject, PIO_STATUS_BLOCK pStatus, int cbSectorLower, int cbSectorTotal, PVOID puchData, UCHAR cWriteDisk )
{
     NTSTATUS          nStatus;
     KEVENT               kEvent;
     PMDL               pMdl = NULL;
     int                    Flags = 0;
     DWORD               cbLength = 0;
     char               cStackSize = pDeviceObject->StackSize;
     PIRP               pIrp = IoAllocateIrp( cStackSize, FALSE );
     PRKTHREAD          pkThread = NULL;
     PRW_SECTOR_CMD     pRWSectorCmd = NULL;
     PIO_STACK_LOCATION stack = NULL;

     if ( NULL == pIrp )
     {
          KdPrint( ( " IoAllocateIrp failed.") );
          goto END;     
     }

     cbLength = cbSectorTotal*512;
     pMdl = IoAllocateMdl( puchData, cbLength, 0, 0, 0 );
     pIrp->MdlAddress = pMdl;
     
     if ( NULL == pMdl )
     {
          KdPrint( ( " IoAllocateMdl failed.") );
          IoFreeIrp( pIrp );
          return -1;
     }

     pIrp->UserEvent = &kEvent;

     __asm
     {
          pushad
          mov          esi, pIrp
          movsx eax, word ptr [esi]
          shl eax, 10h
          or eax, 5
          mov          Flags, eax
          popad
     }
     
     pkThread = KeGetCurrentThread();
     pIrp->IoStatus.Status = 0;
     pIrp->IoStatus.Information = 0;
     pIrp->UserBuffer = 0;
     pIrp->Flags = Flags;
     pIrp->Tail.Overlay.Thread = (PETHREAD)pkThread;          //???
     pIrp->Cancel = FALSE;
     pIrp->CancelRoutine = NULL;
     pIrp->RequestorMode = (KPROCESSOR_MODE)0;

//     初始化IRP 堆栈、发送给下层驱动。
//     char CMajorFunction = pIrp->Tail.Overlay.CurrentStackLocation.MajorFunction;     重点分析下
//     stack = (PIO_STACK_LOCATION)pIrp->Tail.Overlay.CurrentStackLocation;
     
     __asm
     {
          pushad
          mov          esi, pIrp
          mov          edi, [esi+60h]                    //pIrp->Tail.CurrentStackLocation     
          mov          al,      cWriteDisk
          xor          ebx, ebx
          mov [esi+0Ch], ebx                    //pIrp->AssociatedIrp = NULL;
          sub          edi, 0x24                         //?下一层堆栈地址?
          add          al,     3
          mov          [edi],     al                         //stack->MajorFunction = cWriteDisk;
          mov          [edi+2], 0x5c                    //Flags
          mov          [edi+3], 0xE0                    //stack->Control = 0xE0;
          mov          eax, cbLength
          mov          [edi+0x4], eax
          mov          [edi+0x8], ebx
          mov          eax, cbSectorLower
          shl          eax, 9
          mov          [edi+0xc], eax
          mov          [edi+0x10], ebx
          mov          eax, pDeviceObject
          mov [edi+0x14], eax
          mov          esi,     CompletionRoutine
          mov [edi+0x1c], esi                         //stack->CompletionRoutine = CompletionRoutine;
          xor          eax, eax
          mov [edi+0x20], eax                         //stack->Context = 0;
          popad
     }

     MmBuildMdlForNonPagedPool( pIrp->MdlAddress );
     KeInitializeEvent( &kEvent, (EVENT_TYPE)0, 0 );

     nStatus = IoCallDriver( pDeviceObject, pIrp );
     if ( 0x103 == nStatus )     //STATUS_PENDING
     {
          KeWaitForSingleObject( (PVOID)&kEvent, Executive, KernelMode, FALSE, 0 );
     }

END:
     nStatus = pIrp->IoStatus.Information;
     pStatus->Information = nStatus;
     nStatus = pIrp->IoStatus.Status;
     pStatus->Status = nStatus;
     if ( 0 != nStatus )
     {
          pStatus->Information = cbSectorTotal;
     }

     return nStatus;
}