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

View file

@ -53,8 +53,7 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
PCHAR BufferTarget = (PCHAR)Buffer; PCHAR BufferTarget = (PCHAR)Buffer;
LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset; LARGE_INTEGER CacheOffset, EndOfExtent, NextOffset;
DPRINT DPRINT("CcCopyRead(%x,%x,%d,%d,%x)\n",
("CcCopyRead(%x,%x,%d,%d,%x)\n",
FileObject, FileObject,
FileOffset->LowPart, FileOffset->LowPart,
Length, Length,
@ -74,10 +73,12 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
ReadLen = NextOffset.QuadPart - CacheOffset.QuadPart; 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 if (!CcPinRead(FileObject,
(FileObject,
&CacheOffset, &CacheOffset,
ReadLen, ReadLen,
Wait ? PIN_WAIT : PIN_IF_BCB, Wait ? PIN_WAIT : PIN_IF_BCB,
@ -90,11 +91,12 @@ CcCopyRead(IN PFILE_OBJECT FileObject,
return FALSE; return FALSE;
} }
DPRINT("Copying %d bytes at %08x%08x\n", ReadLen, CacheOffset.HighPart, CacheOffset.LowPart); DPRINT("Copying %d bytes at %08x%08x\n",
RtlCopyMemory ReadLen,
(BufferTarget, CacheOffset.HighPart,
ReadBuffer, CacheOffset.LowPart);
ReadLen);
RtlCopyMemory(BufferTarget, ReadBuffer, ReadLen);
BufferTarget += ReadLen; BufferTarget += ReadLen;
@ -142,8 +144,7 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
EndOffset.QuadPart = CurrentOffset.QuadPart + Length; EndOffset.QuadPart = CurrentOffset.QuadPart + Length;
DPRINT DPRINT("CcCopyWrite(%x,%x,%d,%d,%x)\n",
("CcCopyWrite(%x,%x,%d,%d,%x)\n",
FileObject, FileObject,
FileOffset->LowPart, FileOffset->LowPart,
Length, Length,
@ -156,20 +157,35 @@ CcCopyWrite(IN PFILE_OBJECT FileObject,
NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1); NextOffset.LowPart = (CurrentOffset.LowPart + CACHE_STRIPE) & ~(CACHE_STRIPE - 1);
DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart); DPRINT("NextOffset %08x%08x\n", NextOffset.u.HighPart, NextOffset.u.LowPart);
WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length); WriteLen = MIN(NextOffset.QuadPart - CurrentOffset.QuadPart, Length);
DPRINT("Copying %x bytes from %08x%08x\n", DPRINT("Copying %x bytes from %08x%08x\n",
WriteLen, WriteLen,
CurrentOffset.u.HighPart, CurrentOffset.u.LowPart); CurrentOffset.u.HighPart,
CurrentOffset.u.LowPart);
DPRINT("CcPreparePinWrite\n"); 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); (PVOID *)&Bcb, &WriteBuf);
DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf); DPRINT("Result %s %x %x\n", Result ? "TRUE" : "FALSE", Bcb, WriteBuf);
if (!Result) if (!Result)
{ {
DPRINT1("CcPreparePinWrite Failed?\n"); 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); //MiZeroFillSection(WriteBuf, &CurrentOffset, WriteLen);
RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen); RtlCopyMemory(WriteBuf, ((PCHAR)Buffer) + Count, WriteLen);

View file

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

View file

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

View file

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

View file

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