/* FUNCTIONS ******************************************************************/
+/*
+
+CcCopyRead can be called for a region of any size and alignment, so we must
+crawl the cache space, focusing one cache stripe after another and using
+RtlCopyMemory to copy the input data into the cache. In constrained memory,
+pages faulted into new stripes are often taken from old stripes, causing the
+old stripes to be flushed right away. In the case of many short buffered in
+order writes, like the ones generated by stdio, this can be really efficient.
+
+*/
BOOLEAN
NTAPI
CcCopyRead(IN PFILE_OBJECT FileObject,
PVOID Bcb;
PCHAR BufferTarget = (PCHAR)Buffer;
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
-
- DPRINT
- ("CcCopyRead(%x,%x,%d,%d,%x)\n",
- FileObject,
- FileOffset->LowPart,
- Length,
- Wait,
- Buffer);
-
+
+ DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
CacheOffset.QuadPart = FileOffset->QuadPart;
EndOfExtent.QuadPart = FileOffset->QuadPart + Length;
while (CacheOffset.QuadPart < EndOfExtent.QuadPart)
{
- NextOffset.QuadPart = CacheOffset.QuadPart;
- NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
- ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
- if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
- {
- ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
- }
-
- DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
-
- if (!CcPinRead
- (FileObject,
- &CacheOffset,
- ReadLen,
- Wait ? PIN_WAIT : PIN_IF_BCB,
- &Bcb,
- (PVOID*)&ReadBuffer))
- {
- IoStatus->Status = STATUS_UNSUCCESSFUL;
- IoStatus->Information = 0;
- DPRINT("Failed CcCopyRead\n");
- return FALSE;
- }
-
- DPRINT1("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
- RtlCopyMemory
- (BufferTarget,
- ReadBuffer,
- ReadLen);
-
- BufferTarget += ReadLen;
-
- CacheOffset = NextOffset;
- CcUnpinData(Bcb);
+ NextOffset.QuadPart = CacheOffset.QuadPart;
+ NextOffset.LowPart = (NextOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE-1);
+ ReadLen = EndOfExtent.QuadPart - CacheOffset.QuadPart;
+ if (CacheOffset.QuadPart + ReadLen > NextOffset.QuadPart)
+ {
+ ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
+ }
+
+ DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
+ ReadLen,
+ CacheOffset.HighPart,
+ CacheOffset.LowPart);
+
+ if (!CcPinRead(FileObject,
+ &CacheOffset,
+ ReadLen,
+ Wait ? PIN_WAIT : PIN_IF_BCB,
+ &Bcb,
+ (PVOID*)&ReadBuffer))
+ {
+ IoStatus->Status = STATUS_UNSUCCESSFUL;
+ IoStatus->Information = 0;
+ DPRINT("Failed CcCopyRead\n");
+ return FALSE;
+ }
+
+ DPRINT("Copying %d bytes at %08x%08x\n",
+ ReadLen,
+ CacheOffset.HighPart,
+ CacheOffset.LowPart);
+
+ RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
+
+ BufferTarget += ReadLen;
+
+ CacheOffset = NextOffset;
+ CcUnpinData(Bcb);
}
-
+
IoStatus->Status = STATUS_SUCCESS;
IoStatus->Information = Length;
-
+
DPRINT("Done with CcCopyRead\n");
-
+
return TRUE;
}
OUT PVOID Buffer,
OUT PIO_STATUS_BLOCK IoStatus)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
}
BOOLEAN
IN BOOLEAN Wait,
IN PVOID Buffer)
{
- INT Count = 0;
- BOOLEAN Result;
- PNOCC_BCB Bcb;
- PVOID WriteBuf;
- ULONG WriteLen;
- LARGE_INTEGER CurrentOffset = *FileOffset;
- LARGE_INTEGER EndOffset;
- LARGE_INTEGER NextOffset;
-
- EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
-
- DPRINT
- ("CcCopyWrite(%x,%x,%d,%d,%x)\n",
- FileObject,
- FileOffset->LowPart,
- Length,
- Wait,
- Buffer);
-
- while (CurrentOffset.QuadPart < EndOffset.QuadPart)
- {
- NextOffset.HighPart = CurrentOffset.HighPart;
- NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
- DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
- WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
- DPRINT("Copying %x bytes from %08x%08x\n",
- WriteLen,
- CurrentOffset.u.HighPart, CurrentOffset.u.LowPart);
- DPRINT("CcPreparePinWrite\n");
- Result = CcPreparePinWrite
- (FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB,
- (PVOID *)&Bcb, &WriteBuf);
- DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
- if (!Result)
- {
- DPRINT1("CcPreparePinWrite Failed?\n");
- if (Wait) RtlRaiseStatus(STATUS_NOT_MAPPED_DATA); else return FALSE;
- }
- DPRINT1("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n", Bcb - CcCacheSections, WriteBuf, Bcb->BaseAddress);
-
- //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
- RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
- Count += WriteLen;
- Length -= WriteLen;
- CurrentOffset = NextOffset;
- Bcb->Dirty = TRUE;
- CcUnpinData(Bcb);
- }
-
- DPRINT("Done with CcCopyWrite\n");
-
- return TRUE;
+ INT Count = 0;
+ BOOLEAN Result;
+ PNOCC_BCB Bcb;
+ PVOID WriteBuf;
+ ULONG WriteLen;
+ LARGE_INTEGER CurrentOffset = *FileOffset;
+ LARGE_INTEGER EndOffset;
+ LARGE_INTEGER NextOffset;
+
+ EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
+
+ DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
+ FileObject,
+ FileOffset->LowPart,
+ Length,
+ Wait,
+ Buffer);
+
+ while (CurrentOffset.QuadPart < EndOffset.QuadPart)
+ {
+ NextOffset.HighPart = CurrentOffset.HighPart;
+ NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
+ DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
+ WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
+
+ DPRINT("Copying %x bytes from %08x%08x\n",
+ WriteLen,
+ CurrentOffset.u.HighPart,
+ CurrentOffset.u.LowPart);
+
+ DPRINT("CcPreparePinWrite\n");
+
+ Result = CcPreparePinWrite(FileObject,
+ &CurrentOffset,
+ WriteLen,
+ FALSE,
+ Wait ? PIN_WAIT : PIN_IF_BCB,
+ (PVOID *)&Bcb, &WriteBuf);
+
+ DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
+ if (!Result)
+ {
+ DPRINT1("CcPreparePinWrite Failed?\n");
+ if (Wait)
+ RtlRaiseStatus(STATUS_NOT_MAPPED_DATA);
+ else
+ return FALSE;
+ }
+
+ DPRINT("Copying actual memory to BCB#%x (@%x) (from buffer at %x)\n",
+ Bcb - CcCacheSections,
+ WriteBuf,
+ Bcb->BaseAddress);
+
+ //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
+ RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);
+ Count += WriteLen;
+ Length -= WriteLen;
+ CurrentOffset = NextOffset;
+ Bcb->Dirty = TRUE;
+ CcUnpinData(Bcb);
+ }
+
+ DPRINT("Done with CcCopyWrite\n");
+
+ return TRUE;
}
VOID
IN ULONG Length,
IN PVOID Buffer)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
}
BOOLEAN
IN BOOLEAN Wait,
IN UCHAR Retrying)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
return FALSE;
}
IN ULONG BytesToWrite,
IN BOOLEAN Retrying)
{
- UNIMPLEMENTED;
- while (TRUE);
+ UNIMPLEMENTED_DBGBREAK();
}
/* EOF */