[FORMATTING]

* Addendum to r56262.

svn path=/trunk/; revision=56273
This commit is contained in:
Amine Khaldi 2012-03-29 12:14:58 +00:00
parent 4d61c55638
commit aabb4465a0
13 changed files with 1259 additions and 1151 deletions

View file

@ -42,7 +42,7 @@ CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject,
Map->ReadAheadGranularity = Granularity;
}
}
VOID
NTAPI
CcpReadAhead(PVOID Context)
@ -50,11 +50,13 @@ CcpReadAhead(PVOID Context)
LARGE_INTEGER Offset;
PWORK_QUEUE_WITH_READ_AHEAD WorkItem = (PWORK_QUEUE_WITH_READ_AHEAD)Context;
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)WorkItem->FileObject->SectionObjectPointer->SharedCacheMap;
DPRINT1("Reading ahead %08x%08x:%x %wZ\n",
WorkItem->FileOffset.HighPart,
WorkItem->FileOffset.LowPart,
WorkItem->Length,
&WorkItem->FileObject->FileName);
Offset.HighPart = WorkItem->FileOffset.HighPart;
Offset.LowPart = PAGE_ROUND_DOWN(WorkItem->FileOffset.LowPart);
if (Map)
@ -92,22 +94,28 @@ CcScheduleReadAhead(IN PFILE_OBJECT FileObject,
IN ULONG Length)
{
PWORK_QUEUE_WITH_READ_AHEAD WorkItem;
DPRINT("Schedule read ahead %08x%08x:%x %wZ\n",
FileOffset->HighPart,
FileOffset->LowPart,
Length,
&FileObject->FileName);
WorkItem = ExAllocatePool(NonPagedPool, sizeof(*WorkItem));
if (!WorkItem) KeBugCheck(0);
ObReferenceObject(FileObject);
WorkItem->FileObject = FileObject;
WorkItem->FileOffset = *FileOffset;
WorkItem->Length = Length;
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpReadAhead, WorkItem);
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem),
(PWORKER_THREAD_ROUTINE)CcpReadAhead,
WorkItem);
ExQueueWorkItem((PWORK_QUEUE_ITEM)WorkItem, DelayedWorkQueue);
DPRINT("Done\n");
}
VOID
NTAPI
CcSetDirtyPinnedData(IN PVOID BcbVoid,
@ -128,7 +136,7 @@ CcGetFlushedValidData(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
return Result;
}
VOID
NTAPI
@ -171,14 +179,16 @@ _CcpFlushCache(IN PNOCC_CACHE_MAP Map,
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT
("Bcb #%x (@%08x%08x)\n",
DPRINT("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
Bcb->RefCount++;
CcpUnlock();
MiFlushMappedSection(Bcb->BaseAddress, &Bcb->FileOffset, &Map->FileSizes.FileSize, Bcb->Dirty);
MiFlushMappedSection(Bcb->BaseAddress,
&Bcb->FileOffset,
&Map->FileSizes.FileSize,
Bcb->Dirty);
CcpLock();
Bcb->RefCount--;
@ -191,8 +201,10 @@ _CcpFlushCache(IN PNOCC_CACHE_MAP Map,
CcpDereferenceCache((ULONG)(Bcb - CcCacheSections), FALSE);
}
else
{
CcpUnpinData(Bcb, TRUE);
}
}
else
{
ListEntry = ListEntry->Flink;
@ -215,7 +227,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
// Not cached
/* Not cached */
if (!Map)
{
if (IoStatus)
@ -231,8 +243,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
BOOLEAN
NTAPI
CcFlushImageSection
(PSECTION_OBJECT_POINTERS SectionObjectPointer,
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
@ -254,15 +265,13 @@ CcFlushImageSection
switch (FlushType)
{
case MmFlushForDelete:
CcPurgeCacheSection
(SectionObjectPointer,
CcPurgeCacheSection(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
FALSE);
break;
case MmFlushForWrite:
CcFlushCache
(SectionObjectPointer,
CcFlushCache(SectionObjectPointer,
&Bcb->FileOffset,
Bcb->Length,
&IOSB);
@ -273,7 +282,7 @@ CcFlushImageSection
return Result;
}
// Always succeeds for us
/* Always succeeds for us */
PVOID
NTAPI
CcRemapBcb(IN PVOID Bcb)
@ -288,7 +297,7 @@ CcRemapBcb(IN PVOID Bcb)
VOID
NTAPI
CcShutdownSystem()
CcShutdownSystem(VOID)
{
ULONG i, Result;
NTSTATUS Status;
@ -300,24 +309,24 @@ CcShutdownSystem()
PNOCC_BCB Bcb = &CcCacheSections[i];
if (Bcb->SectionObject)
{
DPRINT1
("Evicting #%02x %08x%08x %wZ\n",
DPRINT1("Evicting #%02x %08x%08x %wZ\n",
i,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart,
&MmGetFileObjectForSection
((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
Bcb->FileOffset.u.HighPart,
Bcb->FileOffset.u.LowPart,
&MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject)->FileName);
CcpFlushCache(Bcb->Map, NULL, 0, NULL, TRUE);
Bcb->Dirty = FALSE;
}
}
// Evict all section pages
/* Evict all section pages */
Status = MiRosTrimCache(~0, 0, &Result);
DPRINT1("Done (Evicted %d, Status %x)\n", Result, Status);
}
VOID
NTAPI
CcRepinBcb(IN PVOID Bcb)
@ -342,11 +351,11 @@ CcUnpinRepinnedBcb(IN PVOID Bcb,
{
DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
CcpFlushCache
(RealBcb->Map,
CcpFlushCache(RealBcb->Map,
&RealBcb->FileOffset,
RealBcb->Length,
IoStatus, RealBcb->Dirty);
IoStatus,
RealBcb->Dirty);
}
CcUnpinData(Bcb);

View file

@ -53,8 +53,7 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
PCHAR BufferTarget = (PCHAR)Buffer;
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
DPRINT
("CcCopyRead(%x,%x,%d,%d,%x)\n",
DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
@ -74,10 +73,12 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart;
}
DPRINT("Reading %d bytes in this go (at %08x%08x)\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
DPRINT("Reading %d bytes in this go (at %08x%08x)\n",
ReadLen,
CacheOffset.HighPart,
CacheOffset.LowPart);
if (!CcPinRead
(FileObject,
if (!CcPinRead(FileObject,
&CacheOffset,
ReadLen,
Wait ? PIN_WAIT : PIN_IF_BCB,
@ -90,11 +91,12 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
return FALSE;
}
DPRINT("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart);
RtlCopyMemory
(BufferTarget,
ReadBuffer,
ReadLen);
DPRINT("Copying %d bytes at %08x%08x\n",
ReadLen,
CacheOffset.HighPart,
CacheOffset.LowPart);
RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
BufferTarget += ReadLen;
@ -142,8 +144,7 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
DPRINT
("CcCopyWrite(%x,%x,%d,%d,%x)\n",
DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
FileObject,
FileOffset->LowPart,
Length,
@ -156,20 +157,35 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
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);
CurrentOffset.u.HighPart,
CurrentOffset.u.LowPart);
DPRINT("CcPreparePinWrite\n");
Result = CcPreparePinWrite
(FileObject, &CurrentOffset, WriteLen, FALSE, Wait ? PIN_WAIT : PIN_IF_BCB,
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;
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);
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);

View file

@ -86,7 +86,10 @@ CcInitializeCacheManager(VOID)
DPRINT("Initialize\n");
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait, SynchronizationEvent, FALSE);
KeInitializeEvent(&CcCacheSections[i].ExclusiveWait,
SynchronizationEvent,
FALSE);
InitializeListHead(&CcCacheSections[i].ThisFileList);
}
@ -150,7 +153,8 @@ a stream file object and a sibling file object in the file object struct
itself.
*/
// Must have CcpLock()
/* Must have CcpLock() */
PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
{
PLIST_ENTRY Entry, Private;
@ -158,13 +162,16 @@ PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
Entry != &CcpAllSharedCacheMaps;
Entry = Entry->Flink)
{
// 'Identical' test for other stream file object
/* 'Identical' test for other stream file object */
PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
for (Private = Map->PrivateCacheMaps.Flink;
Private != &Map->PrivateCacheMaps;
Private = Private->Flink)
{
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private, NOCC_PRIVATE_CACHE_MAP, ListEntry);
PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private,
NOCC_PRIVATE_CACHE_MAP,
ListEntry);
if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
PrivateMap->FileObject->Vpb == FileObject->Vpb &&
@ -179,8 +186,8 @@ PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
return 0;
}
// Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html
/* Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */
VOID
NTAPI
CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
@ -197,29 +204,36 @@ CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
stream file object we can take it from. */
if (!Map && FileObject->Flags & FO_STREAM_FILE)
{
PFILE_OBJECT IdenticalStreamFileObject =
CcpFindOtherStreamFileObject(FileObject);
PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
if (IdenticalStreamFileObject)
Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
if (Map)
{
DPRINT1
("Linking SFO %x to previous SFO %x through cache map %x #\n",
FileObject, IdenticalStreamFileObject, Map);
DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
FileObject,
IdenticalStreamFileObject,
Map);
}
}
/* We still don't have a shared cache map. We need to create one. */
if (!Map)
{
DPRINT("Initializing file object for (%p) %wZ\n", FileObject, &FileObject->FileName);
DPRINT("Initializing file object for (%p) %wZ\n",
FileObject,
&FileObject->FileName);
Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
FileObject->SectionObjectPointer->SharedCacheMap = Map;
Map->FileSizes = *FileSizes;
Map->LazyContext = LazyWriteContext;
Map->ReadAheadGranularity = PAGE_SIZE;
RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
// For now ...
DPRINT("FileSizes->ValidDataLength %08x%08x\n", FileSizes->ValidDataLength.HighPart, FileSizes->ValidDataLength.LowPart);
/* For now ... */
DPRINT("FileSizes->ValidDataLength %08x%08x\n",
FileSizes->ValidDataLength.HighPart,
FileSizes->ValidDataLength.LowPart);
InitializeListHead(&Map->AssociatedBcb);
InitializeListHead(&Map->PrivateCacheMaps);
InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
@ -230,7 +244,9 @@ CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
is empty, we know we can delete it. */
if (!PrivateCacheMap)
{
PrivateCacheMap = ExAllocatePool(NonPagedPool, sizeof(*PrivateCacheMap));
PrivateCacheMap = ExAllocatePool(NonPagedPool,
sizeof(*PrivateCacheMap));
FileObject->PrivateCacheMap = PrivateCacheMap;
PrivateCacheMap->FileObject = FileObject;
ObReferenceObject(PrivateCacheMap->FileObject);
@ -257,7 +273,9 @@ CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
PLIST_ENTRY Entry;
ULONG Count;
for (Count = 0, Entry = Map->AssociatedBcb.Flink; Entry != &Map->AssociatedBcb; Entry = Entry->Flink, Count++);
for (Count = 0, Entry = Map->AssociatedBcb.Flink;
Entry != &Map->AssociatedBcb;
Entry = Entry->Flink, Count++);
return Count;
}
@ -272,7 +290,9 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n", &FileObject->FileName, FileObject->SectionObjectPointer);
DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n",
&FileObject->FileName,
FileObject->SectionObjectPointer);
ASSERT(UninitializeEvent == NULL);
@ -297,7 +317,10 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
/* Get rid of all the cache stripes. */
while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink,
NOCC_BCB,
ThisFileList);
DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
Bcb->RefCount = 1;
CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
@ -315,11 +338,10 @@ CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
DPRINT("Uninit complete\n");
/* The return from CcUninitializeCacheMap means that 'caching was stopped'.
*/
/* The return from CcUninitializeCacheMap means that 'caching was stopped'. */
return LastMap;
}
/*
CcSetFileSizes is used to tell the cache manager that the file changed
@ -349,8 +371,7 @@ CcSetFileSizes(IN PFILE_OBJECT FileObject,
BOOLEAN
NTAPI
CcGetFileSizes
(IN PFILE_OBJECT FileObject,
CcGetFileSizes(IN PFILE_OBJECT FileObject,
IN PCC_FILE_SIZES FileSizes)
{
PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
@ -380,7 +401,7 @@ CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
UNIMPLEMENTED;
while (TRUE);
}
/*
This could be implemented much more intelligently by mapping instances
@ -403,10 +424,11 @@ CcZeroData(IN PFILE_OBJECT FileObject,
PVOID PinnedBcb, PinnedBuffer;
PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
DPRINT
("S %08x%08x E %08x%08x\n",
StartOffset->u.HighPart, StartOffset->u.LowPart,
EndOffset->u.HighPart, EndOffset->u.LowPart);
DPRINT("S %08x%08x E %08x%08x\n",
StartOffset->u.HighPart,
StartOffset->u.LowPart,
EndOffset->u.HighPart,
EndOffset->u.LowPart);
if (!Map)
{
@ -425,17 +447,41 @@ CcZeroData(IN PFILE_OBJECT FileObject,
// Handle leading page
if (LowerBound.QuadPart != Target.QuadPart)
{
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart, (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
DPRINT("Zero last half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
(PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
DPRINT("Zero last half %08x%08x %x\n",
Target.u.HighPart,
Target.u.LowPart,
ToWrite);
Status = MiSimpleRead(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
TRUE,
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
RtlRaiseStatus(Status);
}
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart, ToWrite);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE,UpperBound.QuadPart-Target.QuadPart), &IOSB);
DPRINT1("RtlZeroMemory(%x,%x)\n",
ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
ToWrite);
RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
ToWrite);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
MIN(PAGE_SIZE,
UpperBound.QuadPart-Target.QuadPart),
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
@ -449,8 +495,16 @@ CcZeroData(IN PFILE_OBJECT FileObject,
while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
{
DPRINT("Zero full page %08x%08x\n", Target.u.HighPart, Target.u.LowPart);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, PAGE_SIZE, &IOSB);
DPRINT("Zero full page %08x%08x\n",
Target.u.HighPart,
Target.u.LowPart);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
@ -462,8 +516,18 @@ CcZeroData(IN PFILE_OBJECT FileObject,
if (UpperBound.QuadPart > Target.QuadPart)
{
ToWrite = UpperBound.QuadPart - Target.QuadPart;
DPRINT("Zero first half %08x%08x %x\n", Target.u.HighPart, Target.u.LowPart, ToWrite);
Status = MiSimpleRead(FileObject, &Target, ZeroBuf, PAGE_SIZE, TRUE, &IOSB);
DPRINT("Zero first half %08x%08x %x\n",
Target.u.HighPart,
Target.u.LowPart,
ToWrite);
Status = MiSimpleRead(FileObject,
&Target,
ZeroBuf,
PAGE_SIZE,
TRUE,
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
@ -471,7 +535,12 @@ CcZeroData(IN PFILE_OBJECT FileObject,
}
DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
RtlZeroMemory(ZeroBuf, ToWrite);
Status = MiSimpleWrite(FileObject, &Target, ZeroBuf, MIN(PAGE_SIZE, UpperBound.QuadPart-Target.QuadPart), &IOSB);
Status = MiSimpleWrite(FileObject,
&Target,
ZeroBuf,
MIN(PAGE_SIZE,
UpperBound.QuadPart-Target.QuadPart),
&IOSB);
if (!NT_SUCCESS(Status))
{
ExFreePool(ZeroBuf);
@ -495,18 +564,23 @@ CcZeroData(IN PFILE_OBJECT FileObject,
if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
{
DPRINT
("Bcb #%x (@%08x%08x)\n",
DPRINT("Bcb #%x (@%08x%08x)\n",
Bcb - CcCacheSections,
Bcb->FileOffset.u.HighPart, Bcb->FileOffset.u.LowPart);
Bcb->FileOffset.u.HighPart,
Bcb->FileOffset.u.LowPart);
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
LowerBound.QuadPart);
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
UpperBound.QuadPart);
End.QuadPart = MIN(End.QuadPart,
Bcb->FileOffset.QuadPart + Bcb->Length);
Target.QuadPart = MAX(Bcb->FileOffset.QuadPart, LowerBound.QuadPart);
End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart, UpperBound.QuadPart);
End.QuadPart = MIN(End.QuadPart, Bcb->FileOffset.QuadPart + Bcb->Length);
CcpUnlock();
if (!CcPreparePinWrite
(FileObject,
if (!CcPreparePinWrite(FileObject,
&Target,
End.QuadPart - Target.QuadPart,
TRUE,
@ -521,7 +595,7 @@ CcZeroData(IN PFILE_OBJECT FileObject,
CcpLock();
ListEntry = ListEntry->Flink;
// Return from pin state
/* Return from pin state */
CcpUnpinData(PinnedBcb, TRUE);
}
@ -542,7 +616,10 @@ CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
CcpLock();
if (!IsListEmpty(&Map->AssociatedBcb))
{
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink,
NOCC_BCB,
ThisFileList);
Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
}
CcpUnlock();

View file

@ -16,12 +16,10 @@
/* GLOBALS ********************************************************************/
/* FUNCTIONS ******************************************************************/
PMDL
NTAPI
CcpBuildCacheMdl
(PFILE_OBJECT FileObject,
CcpBuildCacheMdl(PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
PIO_STATUS_BLOCK IOSB)
@ -29,8 +27,7 @@ CcpBuildCacheMdl
PMDL Mdl;
PVOID Bcb, Buffer;
BOOLEAN Result = CcMapData
(FileObject,
BOOLEAN Result = CcMapData(FileObject,
FileOffset,
Length,
PIN_WAIT,
@ -47,12 +44,7 @@ CcpBuildCacheMdl
IOSB->Information = Length;
IOSB->Status = STATUS_SUCCESS;
Mdl = IoAllocateMdl
(Buffer,
Length,
FALSE,
FALSE,
NULL);
Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
if (!Mdl)
{
@ -75,13 +67,9 @@ CcMdlRead(IN PFILE_OBJECT FileObject,
OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus)
{
*MdlChain = CcpBuildCacheMdl
(FileObject,
FileOffset,
Length,
IoStatus);
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
}
VOID
NTAPI
CcMdlReadComplete(IN PFILE_OBJECT FileObject,
@ -97,7 +85,7 @@ CcMdlReadComplete2(IN PMDL MdlChain,
{
UNIMPLEMENTED
}
VOID
NTAPI
CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
@ -106,11 +94,7 @@ CcPrepareMdlWrite(IN PFILE_OBJECT FileObject,
OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus)
{
*MdlChain = CcpBuildCacheMdl
(FileObject,
FileOffset,
Length,
IoStatus);
*MdlChain = CcpBuildCacheMdl(FileObject, FileOffset, Length, IoStatus);
}
VOID

View file

@ -40,24 +40,18 @@ typedef struct _NOCC_CACHE_MAP
VOID
NTAPI
CcPfInitializePrefetcher(
VOID
);
CcPfInitializePrefetcher(VOID);
VOID
NTAPI
CcMdlReadComplete2(
IN PMDL MemoryDescriptorList,
IN PFILE_OBJECT FileObject
);
CcMdlReadComplete2(IN PMDL MemoryDescriptorList,
IN PFILE_OBJECT FileObject);
VOID
NTAPI
CcMdlWriteComplete2(
IN PFILE_OBJECT FileObject,
CcMdlWriteComplete2(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain
);
IN PMDL MdlChain);
VOID
NTAPI
@ -65,7 +59,8 @@ CcInitView(VOID);
BOOLEAN
NTAPI
CcpUnpinData(PNOCC_BCB Bcb, BOOLEAN ActuallyRelease);
CcpUnpinData(PNOCC_BCB Bcb,
BOOLEAN ActuallyRelease);
BOOLEAN
NTAPI
@ -82,12 +77,12 @@ CcInitCacheZeroPage(VOID);
/* Called by section.c */
BOOLEAN
NTAPI
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer, MMFLUSH_TYPE FlushType);
CcFlushImageSection(PSECTION_OBJECT_POINTERS SectionObjectPointer,
MMFLUSH_TYPE FlushType);
VOID
NTAPI
_CcpFlushCache
(IN PNOCC_CACHE_MAP Map,
_CcpFlushCache(IN PNOCC_CACHE_MAP Map,
IN OPTIONAL PLARGE_INTEGER FileOffset,
IN ULONG Length,
OUT OPTIONAL PIO_STATUS_BLOCK IoStatus,
@ -99,7 +94,8 @@ _CcpFlushCache
BOOLEAN
NTAPI
CcGetFileSizes(PFILE_OBJECT FileObject, PCC_FILE_SIZES FileSizes);
CcGetFileSizes(PFILE_OBJECT FileObject,
PCC_FILE_SIZES FileSizes);
ULONG
NTAPI
@ -149,10 +145,10 @@ extern VOID _CcpUnlock(const char *file, int line);
extern VOID CcpReferenceCache(ULONG Sector);
extern VOID CcpDereferenceCache(ULONG Sector, BOOLEAN Immediate);
BOOLEAN
NTAPI
CcpMapData
(IN PFILE_OBJECT FileObject,
CcpMapData(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,

View file

@ -19,6 +19,7 @@
* it maps the cache sections read only until they're pinned writable, and then
* turns them readonly again when they're unpinned.
* This helped me determine that a certain bug was not a memory overwrite. */
//#define PIN_WRITE_ONLY
/*
@ -106,13 +107,18 @@ LONG CcOutstandingDeletes;
/* FUNCTIONS ******************************************************************/
PETHREAD LastThread;
VOID _CcpLock(const char *file, int line)
VOID
_CcpLock(const char *file,
int line)
{
//DPRINT("<<<---<<< CC In Mutex(%s:%d %x)!\n", file, line, PsGetCurrentThread());
ExAcquireFastMutex(&CcMutex);
}
VOID _CcpUnlock(const char *file, int line)
VOID
_CcpUnlock(const char *file,
int line)
{
ExReleaseFastMutex(&CcMutex);
//DPRINT(">>>--->>> CC Exit Mutex!\n", file, line);
@ -130,8 +136,8 @@ should not count when determining whether the file can be resized.
*/
NTSTATUS CcpAllocateSection
(PFILE_OBJECT FileObject,
NTSTATUS
CcpAllocateSection(PFILE_OBJECT FileObject,
ULONG Length,
ULONG Protect,
PROS_SECTION_OBJECT *Result)
@ -143,8 +149,8 @@ NTSTATUS CcpAllocateSection
DPRINT("Making Section for File %x\n", FileObject);
DPRINT("File name %wZ\n", &FileObject->FileName);
Status = MmCreateSection
((PVOID*)Result,
Status = MmCreateSection((PVOID*)Result,
STANDARD_RIGHTS_REQUIRED,
NULL,
&MaxSize,
@ -203,7 +209,9 @@ this.
*/
/* Must have acquired the mutex */
VOID CcpDereferenceCache(ULONG Start, BOOLEAN Immediate)
VOID
CcpDereferenceCache(ULONG Start,
BOOLEAN Immediate)
{
PVOID ToUnmap;
PNOCC_BCB Bcb;
@ -265,7 +273,9 @@ VOID CcpDereferenceCache(ULONG Start, BOOLEAN Immediate)
WorkItem->ReleaseFromLazyWrite = Bcb->Map->Callbacks.ReleaseFromLazyWrite;
WorkItem->LazyContext = Bcb->Map->LazyContext;
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem), (PWORKER_THREAD_ROUTINE)CcpUnmapCache, WorkItem);
ExInitializeWorkItem(((PWORK_QUEUE_ITEM)WorkItem),
(PWORKER_THREAD_ROUTINE)CcpUnmapCache,
WorkItem);
Bcb->Map = NULL;
Bcb->SectionObject = NULL;
@ -296,8 +306,8 @@ on failure.
*/
/* Needs mutex */
ULONG CcpAllocateCacheSections
(PFILE_OBJECT FileObject,
ULONG
CcpAllocateCacheSections(PFILE_OBJECT FileObject,
PROS_SECTION_OBJECT SectionObject)
{
ULONG i = INVALID_CACHE;
@ -354,7 +364,8 @@ ULONG CcpAllocateCacheSections
}
/* Must have acquired the mutex */
VOID CcpReferenceCache(ULONG Start)
VOID
CcpReferenceCache(ULONG Start)
{
PNOCC_BCB Bcb;
Bcb = &CcCacheSections[Start];
@ -364,7 +375,8 @@ VOID CcpReferenceCache(ULONG Start)
}
VOID CcpMarkForExclusive(ULONG Start)
VOID
CcpMarkForExclusive(ULONG Start)
{
PNOCC_BCB Bcb;
Bcb = &CcCacheSections[Start];
@ -380,11 +392,17 @@ Bcb.
*/
/* Must not have the mutex */
VOID CcpReferenceCacheExclusive(ULONG Start)
VOID
CcpReferenceCacheExclusive(ULONG Start)
{
PNOCC_BCB Bcb = &CcCacheSections[Start];
KeWaitForSingleObject(&Bcb->ExclusiveWait, Executive, KernelMode, FALSE, NULL);
KeWaitForSingleObject(&Bcb->ExclusiveWait,
Executive,
KernelMode,
FALSE,
NULL);
CcpLock();
ASSERT(Bcb->ExclusiveWaiter);
ASSERT(Bcb->SectionObject);
@ -408,7 +426,10 @@ Returns a valid index or INVALID_CACHE.
*/
/* Must have the mutex */
ULONG CcpFindMatchingMap(PLIST_ENTRY Head, PLARGE_INTEGER FileOffset, ULONG Length)
ULONG
CcpFindMatchingMap(PLIST_ENTRY Head,
PLARGE_INTEGER FileOffset,
ULONG Length)
{
PLIST_ENTRY Entry;
//DPRINT("Find Matching Map: (%x) %x:%x\n", FileOffset->LowPart, Length);
@ -441,8 +462,7 @@ possibly evicting another stripe in order to get our stripe.
BOOLEAN
NTAPI
CcpMapData
(IN PFILE_OBJECT FileObject,
CcpMapData(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
@ -466,7 +486,11 @@ CcpMapData
return FALSE;
}
DPRINT("CcMapData(F->%x,%08x%08x:%d)\n", FileObject, FileOffset->HighPart, FileOffset->LowPart, Length);
DPRINT("CcMapData(F->%x,%08x%08x:%d)\n",
FileObject,
FileOffset->HighPart,
FileOffset->LowPart,
Length);
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
@ -485,8 +509,8 @@ CcpMapData
Success = TRUE;
*BcbResult = Bcb;
*Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart);
DPRINT
("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
DPRINT("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
Bcb - CcCacheSections,
Bcb->FileOffset.HighPart,
Bcb->FileOffset.LowPart,
@ -495,11 +519,14 @@ CcpMapData
*Buffer,
Length,
&FileObject->FileName);
DPRINT("w1n\n");
goto cleanup;
}
DPRINT("File size %08x%08x\n", Map->FileSizes.ValidDataLength.HighPart, Map->FileSizes.ValidDataLength.LowPart);
DPRINT("File size %08x%08x\n",
Map->FileSizes.ValidDataLength.HighPart,
Map->FileSizes.ValidDataLength.LowPart);
/* Not all files have length, in fact filesystems often use stream file
objects for various internal purposes and are loose about the file
@ -508,7 +535,8 @@ CcpMapData
to have the full stripe worth of space. */
if (Map->FileSizes.ValidDataLength.QuadPart)
{
SectionSize = min(CACHE_STRIPE, Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart);
SectionSize = min(CACHE_STRIPE,
Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart);
}
else
{
@ -517,13 +545,13 @@ CcpMapData
DPRINT("Allocating a cache stripe at %x:%d\n",
Target.LowPart, SectionSize);
//ASSERT(SectionSize <= CACHE_STRIPE);
CcpUnlock();
/* CcpAllocateSection doesn't need the lock, so we'll give other action
a chance in here. */
Status = CcpAllocateSection
(FileObject,
Status = CcpAllocateSection(FileObject,
SectionSize,
#ifdef PIN_WRITE_ONLY
PAGE_READONLY,
@ -553,10 +581,17 @@ retry:
for (i = 0; i < CACHE_NUM_SECTIONS; i++)
{
if (!(i % 64)) DbgPrint("\n");
DbgPrint("%c", CcCacheSections[i].RefCount + (RtlTestBit(CcCacheBitmap, i) ? '@' : '`'));
DbgPrint("%c",
CcCacheSections[i].RefCount + (RtlTestBit(CcCacheBitmap, i) ? '@' : '`'));
}
DbgPrint("\n");
KeWaitForSingleObject(&CcDeleteEvent, Executive, KernelMode, FALSE, NULL);
KeWaitForSingleObject(&CcDeleteEvent,
Executive,
KernelMode,
FALSE,
NULL);
goto retry;
}
@ -578,14 +613,12 @@ retry:
that are specific to NewCC. In this case, it's implementation
exactly mirrors MmMapViewInSystemSpace, but allows an offset to
be specified. */
Status = MmMapCacheViewInSystemSpaceAtOffset
(SectionObject->Segment,
Status = MmMapCacheViewInSystemSpaceAtOffset(SectionObject->Segment,
&Bcb->BaseAddress,
&Target,
&ViewSize);
/* Summary: Failure. Dereference our section and tell the user we failed
*/
/* Summary: Failure. Dereference our section and tell the user we failed */
if (!NT_SUCCESS(Status))
{
*BcbResult = NULL;
@ -604,7 +637,9 @@ retry:
Success = TRUE;
//DPRINT("w1n\n");
Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart, CACHE_STRIPE);
Bcb->Length = MIN(Map->FileSizes.ValidDataLength.QuadPart - Target.QuadPart,
CACHE_STRIPE);
Bcb->SectionObject = SectionObject;
Bcb->Map = Map;
Bcb->FileOffset = Target;
@ -614,8 +649,7 @@ retry:
*Buffer = ((PCHAR)Bcb->BaseAddress) + (int)(FileOffset->QuadPart - Bcb->FileOffset.QuadPart);
FaultIn = TRUE;
DPRINT
("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
DPRINT("Bcb #%x Buffer maps (%08x%08x) At %x Length %x (Getting %x:%x) %wZ\n",
Bcb - CcCacheSections,
Bcb->FileOffset.HighPart,
Bcb->FileOffset.LowPart,
@ -626,7 +660,8 @@ retry:
&FileObject->FileName);
EndInterval.QuadPart = Bcb->FileOffset.QuadPart + Bcb->Length - 1;
ASSERT((EndInterval.QuadPart & ~(CACHE_STRIPE - 1)) == (Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1)));
ASSERT((EndInterval.QuadPart & ~(CACHE_STRIPE - 1)) ==
(Bcb->FileOffset.QuadPart & ~(CACHE_STRIPE - 1)));
//DPRINT("TERM!\n");
@ -636,21 +671,23 @@ cleanup:
{
if (FaultIn)
{
// Fault in the pages. This forces reads to happen now.
/* Fault in the pages. This forces reads to happen now. */
ULONG i;
PCHAR FaultIn = Bcb->BaseAddress;
DPRINT
("Faulting in pages at this point: file %wZ %08x%08x:%x\n",
DPRINT("Faulting in pages at this point: file %wZ %08x%08x:%x\n",
&FileObject->FileName,
Bcb->FileOffset.HighPart,
Bcb->FileOffset.LowPart,
Bcb->Length);
for (i = 0; i < Bcb->Length; i += PAGE_SIZE)
{
FaultIn[i] ^= 0;
}
}
ASSERT(Bcb >= CcCacheSections && Bcb < (CcCacheSections + CACHE_NUM_SECTIONS));
ASSERT(Bcb >= CcCacheSections &&
Bcb < (CcCacheSections + CACHE_NUM_SECTIONS));
}
else
{
@ -662,8 +699,7 @@ cleanup:
BOOLEAN
NTAPI
CcMapData
(IN PFILE_OBJECT FileObject,
CcMapData(IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
@ -672,8 +708,7 @@ CcMapData
{
BOOLEAN Result;
Result = CcpMapData
(FileObject,
Result = CcpMapData(FileObject,
FileOffset,
Length,
Flags,
@ -683,7 +718,10 @@ CcMapData
if (Result)
{
PNOCC_BCB Bcb = (PNOCC_BCB)*BcbResult;
ASSERT(Bcb >= CcCacheSections && Bcb < CcCacheSections + CACHE_NUM_SECTIONS);
ASSERT(Bcb >= CcCacheSections &&
Bcb < CcCacheSections + CACHE_NUM_SECTIONS);
ASSERT(Bcb->BaseAddress);
CcpLock();
CcpReferenceCache(Bcb - CcCacheSections);
@ -779,12 +817,7 @@ CcPinRead(IN PFILE_OBJECT FileObject,
PNOCC_BCB RealBcb;
BOOLEAN Result;
Result = CcPinMappedData
(FileObject,
FileOffset,
Length,
Flags,
Bcb);
Result = CcPinMappedData(FileObject, FileOffset, Length, Flags, Bcb);
if (Result)
{
@ -796,7 +829,7 @@ CcPinRead(IN PFILE_OBJECT FileObject,
return Result;
}
BOOLEAN
NTAPI
CcPreparePinWrite(IN PFILE_OBJECT FileObject,
@ -817,13 +850,7 @@ CcPreparePinWrite(IN PFILE_OBJECT FileObject,
DPRINT("CcPreparePinWrite(%x:%x)\n", Buffer, Length);
Result = CcPinRead
(FileObject,
FileOffset,
Length,
Flags,
Bcb,
Buffer);
Result = CcPinRead(FileObject, FileOffset, Length, Flags, Bcb, Buffer);
if (Result)
{
@ -834,8 +861,7 @@ CcPreparePinWrite(IN PFILE_OBJECT FileObject,
BaseAddress = RealBcb->BaseAddress;
NumberOfBytes = RealBcb->Length;
MiProtectVirtualMemory
(NULL,
MiProtectVirtualMemory(NULL,
&BaseAddress,
&NumberOfBytes,
PAGE_READWRITE,
@ -847,8 +873,7 @@ CcPreparePinWrite(IN PFILE_OBJECT FileObject,
if (Zero)
{
DPRINT
("Zero fill #%x %08x%08x:%x Buffer %x %wZ\n",
DPRINT("Zero fill #%x %08x%08x:%x Buffer %x %wZ\n",
RealBcb - CcCacheSections,
FileOffset->u.HighPart,
FileOffset->u.LowPart,
@ -923,8 +948,7 @@ CcpUnpinData(IN PNOCC_BCB RealBcb, BOOLEAN ReleaseBit)
SIZE_T NumberOfBytes = RealBcb->Length;
ULONG OldProtect;
MiProtectVirtualMemory
(NULL,
MiProtectVirtualMemory(NULL,
&BaseAddress,
&NumberOfBytes,
PAGE_READONLY,
@ -934,7 +958,7 @@ CcpUnpinData(IN PNOCC_BCB RealBcb, BOOLEAN ReleaseBit)
return TRUE;
}
VOID
NTAPI
CcUnpinData(IN PVOID Bcb)
@ -943,7 +967,9 @@ CcUnpinData(IN PVOID Bcb)
ULONG Selected = RealBcb - CcCacheSections;
BOOLEAN Released;
ASSERT(RealBcb >= CcCacheSections && RealBcb - CcCacheSections < CACHE_NUM_SECTIONS);
ASSERT(RealBcb >= CcCacheSections &&
RealBcb - CcCacheSections < CACHE_NUM_SECTIONS);
DPRINT("CcUnpinData Bcb #%x (RefCount %d)\n", Selected, RealBcb->RefCount);
CcpLock();
@ -968,7 +994,7 @@ CcSetBcbOwnerPointer(IN PVOID Bcb,
RealBcb->OwnerPointer = OwnerPointer;
CcpUnlock();
}
VOID
NTAPI
CcUnpinDataForThread(IN PVOID Bcb,