ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

NTSTATUS NTAPI ReadCacheSegmentChain ( PBCB  Bcb,
ULONG  ReadOffset,
ULONG  Length,
PVOID  Buffer 
)

Definition at line 57 of file copy.c.

Referenced by CcCopyRead().

{
  PCACHE_SEGMENT head;
  PCACHE_SEGMENT current;
  PCACHE_SEGMENT previous;
  IO_STATUS_BLOCK Iosb;
  LARGE_INTEGER SegOffset;
  NTSTATUS Status;
  ULONG TempLength;
  KEVENT Event;
  PMDL Mdl;

  Mdl = _alloca(MmSizeOfMdl(NULL, MAX_RW_LENGTH));

  Status = CcRosGetCacheSegmentChain(Bcb, ReadOffset, Length, &head);
  if (!NT_SUCCESS(Status))
    {
      return(Status);
    }
  current = head;
  while (current != NULL)
    {
      /*
       * If the current segment is valid then copy it into the
       * user buffer.
       */
      if (current->Valid)
    {
      TempLength = min(Bcb->CacheSegmentSize, Length);
      memcpy(Buffer, current->BaseAddress, TempLength);

      Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength);

      Length = Length - TempLength;
      previous = current;
      current = current->NextInChain;
      CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
    }
      /*
       * Otherwise read in as much as we can.
       */
      else
    {
      PCACHE_SEGMENT current2;
      ULONG current_size;
      ULONG i;
      PPFN_NUMBER MdlPages;

      /*
       * Count the maximum number of bytes we could read starting
       * from the current segment.
       */
      current2 = current;
      current_size = 0;
      while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH)
        {
          current2 = current2->NextInChain;
          current_size += Bcb->CacheSegmentSize;
        }

      /*
       * Create an MDL which contains all their pages.
       */
          MmInitializeMdl(Mdl, NULL, current_size);
      Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
      current2 = current;
      current_size = 0;
      MdlPages = (PPFN_NUMBER)(Mdl + 1);
      while (current2 != NULL && !current2->Valid && current_size < MAX_RW_LENGTH)
        {
          PVOID address = current2->BaseAddress;
          for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++, address = RVA(address, PAGE_SIZE))
        {
          *MdlPages++ = MmGetPfnForProcess(NULL, address);
        }
          current2 = current2->NextInChain;
          current_size += Bcb->CacheSegmentSize;
        }

      /*
       * Read in the information.
       */
      SegOffset.QuadPart = current->FileOffset;
      KeInitializeEvent(&Event, NotificationEvent, FALSE);
      Status = IoPageRead(Bcb->FileObject,
                  Mdl,
                  &SegOffset,
                  &Event,
                  &Iosb);
      if (Status == STATUS_PENDING)
      {
         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
         Status = Iosb.Status;
      }
          if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
          {
         MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
      }
      if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
        {
          while (current != NULL)
        {
          previous = current;
          current = current->NextInChain;
          CcRosReleaseCacheSegment(Bcb, previous, FALSE, FALSE, FALSE);
        }
          return(Status);
        }
      current_size = 0;
      while (current != NULL && !current->Valid && current_size < MAX_RW_LENGTH)
        {
          previous = current;
          current = current->NextInChain;
          TempLength = min(Bcb->CacheSegmentSize, Length);
          memcpy(Buffer, previous->BaseAddress, TempLength);

          Buffer = (PVOID)((ULONG_PTR)Buffer + TempLength);

          Length = Length - TempLength;
          CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
          current_size += Bcb->CacheSegmentSize;
        }
    }
    }
  return(STATUS_SUCCESS);
}

Generated on Sun May 27 2012 04:45:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.