首页 >> 编程开发 >> 其他 >> 正文

reactos操作系统实现(87)

  应用程序对设备I/O进行Win32调用,这个调用由I/O系统服务接收,然后I/O管理器从这个请求构造一个合适的I/O请求包(IRP)。那么I/O管理器是怎么样创建这个I/O请求包(IRP)的呢?又是怎么样传送给驱动程序的呢?我们带着这两个问题来分析下面实现文件读取的代码,如下:

#001  NTSTATUS
#002  NTAPI
#003  NtReadFile(IN HANDLE FileHandle,
#004             IN HANDLE Event OPTIONAL,
#005             IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
#006             IN PVOID ApcContext OPTIONAL,
#007             OUT PIO_STATUS_BLOCK IoStatusBlock,
#008             OUT PVOID Buffer,
#009             IN ULONG Length,
#010             IN PLARGE_INTEGER ByteOffset OPTIONAL,
#011             IN PULONG Key OPTIONAL)
#012  {
#013      NTSTATUS Status = STATUS_SUCCESS;
#014      PFILE_OBJECT FileObject;
#015      PIRP Irp;
#016      PDEVICE_OBJECT DeviceObject;
#017      PIO_STACK_LOCATION StackPtr;
#018      KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
#019      PKEVENT EventObject = NULL;
#020      LARGE_INTEGER CapturedByteOffset;
#021      ULONG CapturedKey = 0;
#022      BOOLEAN Synchronous = FALSE;
#023      PMDL Mdl;
#024      PAGED_CODE();
#025      CapturedByteOffset.QuadPart = 0;
#026      IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle);
#027

  检查是否在用户模式调用。

#028      /* Validate User-Mode Buffers */
#029      if(PreviousMode != KernelMode)
#030      {

  使用SEH机制,以便截取异常。

#031          _SEH2_TRY
#032          {

  检测状态块。

#033              /* Probe the status block */
#034              ProbeForWriteIoStatusBlock(IoStatusBlock);
#035 

  检查读取缓冲区。

#036              /* Probe the read buffer */
#037              ProbeForWrite(Buffer, Length, 1);
#038 
#039              /* Check if we got a byte offset */
#040              if (ByteOffset)
#041              {
#042                  /* Capture and probe it */
#043                  CapturedByteOffset = ProbeForReadLargeInteger(ByteOffset);
#044              }
#045 
#046              /* Capture and probe the key */
#047              if (Key) CapturedKey = ProbeForReadUlong(Key);
#048          }
#049          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
#050          {
#051              /* Get the exception code */
#052              Status = _SEH2_GetExceptionCode();
#053          }
#054          _SEH2_END;
#055 
#056          /* Check for probe failure */
#057          if (!NT_SUCCESS(Status)) return Status;
#058      }
#059      else
#060      {
#061          /* Kernel mode: capture directly */
#062          if (ByteOffset) CapturedByteOffset = *ByteOffset;
#063          if (Key) CapturedKey = *Key;
#064      }
#065 

  获取文件对象。

#066      /* Get File Object */
#067      Status = ObReferenceObjectByHandle(FileHandle,
#068                                         FILE_READ_DATA,
#069                                         IoFileObjectType,
#070                                         PreviousMode,
#071                                         (PVOID*)&FileObject,
#072                                         NULL);
#073      if (!NT_SUCCESS(Status)) return Status;
#074