Home | Info | Community | Development | myReactOS | Contact Us
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); }