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

fssup.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Kernel
00004  * FILE:            ntoskrnl/cache/fssup.c
00005  * PURPOSE:         Logging and configuration routines
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  *                  Art Yerkes
00008  */
00009 
00010 /* INCLUDES *******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #include "newcc.h"
00014 #include "section/newmm.h"
00015 #define NDEBUG
00016 #include <debug.h>
00017 
00018 /* GLOBALS ********************************************************************/
00019 
00020 PFSN_PREFETCHER_GLOBALS CcPfGlobals;
00021 extern LONG CcOutstandingDeletes;
00022 extern KEVENT CcpLazyWriteEvent;
00023 extern KEVENT CcFinalizeEvent;
00024 extern VOID NTAPI CcpUnmapThread(PVOID Unused);
00025 extern VOID NTAPI CcpLazyWriteThread(PVOID Unused);
00026 HANDLE CcUnmapThreadHandle, CcLazyWriteThreadHandle;
00027 CLIENT_ID CcUnmapThreadId, CcLazyWriteThreadId;
00028 FAST_MUTEX GlobalPageOperation;
00029 
00030 /*
00031 
00032 A note about private cache maps.
00033 
00034 CcInitializeCacheMap and CcUninitializeCacheMap are not meant to be paired,
00035 although they can work that way.
00036 
00037 The actual operation I've gleaned from reading both jan kratchovil's writing
00038 and real filesystems is this:
00039 
00040 CcInitializeCacheMap means:
00041 
00042 Make the indicated FILE_OBJECT have a private cache map if it doesn't already
00043 and make it have a shared cache map if it doesn't already.
00044 
00045 CcUninitializeCacheMap means:
00046 
00047 Take away the private cache map from this FILE_OBJECT.  If it's the last
00048 private cache map corresponding to a specific shared cache map (the one that
00049 was present in the FILE_OBJECT when it was created), then delete that too,
00050 flusing all cached information.
00051 
00052 Using these simple semantics, filesystems can do all the things they actually
00053 do:
00054 
00055 - Copy out the shared cache map pointer from a newly initialized file object
00056 and store it in the fcb cache.
00057 - Copy it back into any file object and call CcInitializeCacheMap to make
00058 that file object be associated with the caching of all the other siblings.
00059 - Call CcUninitializeCacheMap on a FILE_OBJECT many times, but have only the
00060 first one count for each specific FILE_OBJECT.
00061 - Have the actual last call to CcUninitializeCacheMap (that is, the one that
00062 causes zero private cache maps to be associated with a shared cache map) to
00063 delete the cache map and flush.
00064 
00065 So private cache map here is a light weight structure that just remembers
00066 what shared cache map it associates with.
00067 
00068  */
00069 typedef struct _NOCC_PRIVATE_CACHE_MAP
00070 {
00071     LIST_ENTRY ListEntry;
00072     PFILE_OBJECT FileObject;
00073     PNOCC_CACHE_MAP Map;
00074 } NOCC_PRIVATE_CACHE_MAP, *PNOCC_PRIVATE_CACHE_MAP;
00075 
00076 LIST_ENTRY CcpAllSharedCacheMaps;
00077 
00078 /* FUNCTIONS ******************************************************************/
00079 
00080 BOOLEAN
00081 NTAPI
00082 CcInitializeCacheManager(VOID)
00083 {
00084     int i;
00085 
00086     DPRINT("Initialize\n");
00087     for (i = 0; i < CACHE_NUM_SECTIONS; i++)
00088     {
00089         KeInitializeEvent(&CcCacheSections[i].ExclusiveWait,
00090                           SynchronizationEvent,
00091                           FALSE);
00092 
00093         InitializeListHead(&CcCacheSections[i].ThisFileList);
00094     }
00095 
00096     InitializeListHead(&CcpAllSharedCacheMaps);
00097 
00098     KeInitializeEvent(&CcDeleteEvent, SynchronizationEvent, FALSE);
00099     KeInitializeEvent(&CcFinalizeEvent, SynchronizationEvent, FALSE);
00100     KeInitializeEvent(&CcpLazyWriteEvent, SynchronizationEvent, FALSE);
00101 
00102     CcCacheBitmap->Buffer = ((PULONG)&CcCacheBitmap[1]);
00103     CcCacheBitmap->SizeOfBitMap = ROUND_UP(CACHE_NUM_SECTIONS, 32);
00104     DPRINT1("Cache has %d entries\n", CcCacheBitmap->SizeOfBitMap);
00105     ExInitializeFastMutex(&CcMutex);
00106 
00107     return TRUE;
00108 }
00109 
00110 VOID
00111 NTAPI
00112 CcPfInitializePrefetcher(VOID)
00113 {
00114     /* Notify debugger */
00115     DbgPrintEx(DPFLTR_PREFETCHER_ID,
00116                DPFLTR_TRACE_LEVEL,
00117                "CCPF: InitializePrefetecher()\n");
00118 
00119     /* Setup the Prefetcher Data */
00120     InitializeListHead(&CcPfGlobals.ActiveTraces);
00121     InitializeListHead(&CcPfGlobals.CompletedTraces);
00122     ExInitializeFastMutex(&CcPfGlobals.CompletedTracesLock);
00123 
00124     /* FIXME: Setup the rest of the prefetecher */
00125 }
00126 
00127 BOOLEAN
00128 NTAPI
00129 CcpAcquireFileLock(PNOCC_CACHE_MAP Map)
00130 {
00131     DPRINT("Calling AcquireForLazyWrite: %x\n", Map->LazyContext);
00132     return Map->Callbacks.AcquireForLazyWrite(Map->LazyContext, TRUE);
00133 }
00134 
00135 VOID
00136 NTAPI
00137 CcpReleaseFileLock(PNOCC_CACHE_MAP Map)
00138 {
00139     DPRINT("Releasing Lazy Write %x\n", Map->LazyContext);
00140     Map->Callbacks.ReleaseFromLazyWrite(Map->LazyContext);
00141 }
00142 
00143 /*
00144 
00145 Cc functions are required to treat alternate streams of a file as the same
00146 for the purpose of caching, meaning that we must be able to find the shared
00147 cache map associated with the ``real'' stream associated with a stream file
00148 object, if one exists.  We do that by identifying a private cache map in
00149 our gamut that has the same volume, device and fscontext as the stream file
00150 object we're holding.  It's heavy but it does work.  This can probably be
00151 improved, although there doesn't seem to be any real association between
00152 a stream file object and a sibling file object in the file object struct
00153 itself.
00154 
00155  */
00156 
00157 /* Must have CcpLock() */
00158 PFILE_OBJECT CcpFindOtherStreamFileObject(PFILE_OBJECT FileObject)
00159 {
00160     PLIST_ENTRY Entry, Private;
00161     for (Entry = CcpAllSharedCacheMaps.Flink;
00162          Entry != &CcpAllSharedCacheMaps;
00163          Entry = Entry->Flink)
00164     {
00165         /* 'Identical' test for other stream file object */
00166         PNOCC_CACHE_MAP Map = CONTAINING_RECORD(Entry, NOCC_CACHE_MAP, Entry);
00167         for (Private = Map->PrivateCacheMaps.Flink;
00168              Private != &Map->PrivateCacheMaps;
00169              Private = Private->Flink)
00170         {
00171             PNOCC_PRIVATE_CACHE_MAP PrivateMap = CONTAINING_RECORD(Private,
00172                                                                    NOCC_PRIVATE_CACHE_MAP,
00173                                                                    ListEntry);
00174 
00175             if (PrivateMap->FileObject->Flags & FO_STREAM_FILE &&
00176                 PrivateMap->FileObject->DeviceObject == FileObject->DeviceObject &&
00177                 PrivateMap->FileObject->Vpb == FileObject->Vpb &&
00178                 PrivateMap->FileObject->FsContext == FileObject->FsContext &&
00179                 PrivateMap->FileObject->FsContext2 == FileObject->FsContext2 &&
00180                 1)
00181             {
00182                 return PrivateMap->FileObject;
00183             }
00184         }
00185     }
00186     return 0;
00187 }
00188 
00189 /* Thanks: http://windowsitpro.com/Windows/Articles/ArticleID/3864/pg/2/2.html */
00190 
00191 VOID
00192 NTAPI
00193 CcInitializeCacheMap(IN PFILE_OBJECT FileObject,
00194                      IN PCC_FILE_SIZES FileSizes,
00195                      IN BOOLEAN PinAccess,
00196                      IN PCACHE_MANAGER_CALLBACKS Callbacks,
00197                      IN PVOID LazyWriteContext)
00198 {
00199     PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
00200     PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
00201 
00202     CcpLock();
00203     /* We don't have a shared cache map.  First find out if we have a sibling
00204        stream file object we can take it from. */
00205     if (!Map && FileObject->Flags & FO_STREAM_FILE)
00206     {
00207         PFILE_OBJECT IdenticalStreamFileObject = CcpFindOtherStreamFileObject(FileObject);
00208         if (IdenticalStreamFileObject)
00209             Map = IdenticalStreamFileObject->SectionObjectPointer->SharedCacheMap;
00210         if (Map)
00211         {
00212             DPRINT1("Linking SFO %x to previous SFO %x through cache map %x #\n",
00213                     FileObject,
00214                     IdenticalStreamFileObject,
00215                     Map);
00216         }
00217     }
00218     /* We still don't have a shared cache map.  We need to create one. */
00219     if (!Map)
00220     {
00221         DPRINT("Initializing file object for (%p) %wZ\n",
00222                FileObject,
00223                &FileObject->FileName);
00224 
00225         Map = ExAllocatePool(NonPagedPool, sizeof(NOCC_CACHE_MAP));
00226         FileObject->SectionObjectPointer->SharedCacheMap = Map;
00227         Map->FileSizes = *FileSizes;
00228         Map->LazyContext = LazyWriteContext;
00229         Map->ReadAheadGranularity = PAGE_SIZE;
00230         RtlCopyMemory(&Map->Callbacks, Callbacks, sizeof(*Callbacks));
00231 
00232         /* For now ... */
00233         DPRINT("FileSizes->ValidDataLength %08x%08x\n",
00234                FileSizes->ValidDataLength.HighPart,
00235                FileSizes->ValidDataLength.LowPart);
00236 
00237         InitializeListHead(&Map->AssociatedBcb);
00238         InitializeListHead(&Map->PrivateCacheMaps);
00239         InsertTailList(&CcpAllSharedCacheMaps, &Map->Entry);
00240         DPRINT("New Map %x\n", Map);
00241     }
00242     /* We don't have a private cache map.  Link it with the shared cache map
00243        to serve as a held reference. When the list in the shared cache map
00244        is empty, we know we can delete it. */
00245     if (!PrivateCacheMap)
00246     {
00247         PrivateCacheMap = ExAllocatePool(NonPagedPool,
00248                                          sizeof(*PrivateCacheMap));
00249 
00250         FileObject->PrivateCacheMap = PrivateCacheMap;
00251         PrivateCacheMap->FileObject = FileObject;
00252         ObReferenceObject(PrivateCacheMap->FileObject);
00253     }
00254 
00255     PrivateCacheMap->Map = Map;
00256     InsertTailList(&Map->PrivateCacheMaps, &PrivateCacheMap->ListEntry);
00257 
00258     CcpUnlock();
00259 }
00260 
00261 /*
00262 
00263 This function is used by NewCC's MM to determine whether any section objects
00264 for a given file are not cache sections.  If that's true, we're not allowed
00265 to resize the file, although nothing actually prevents us from doing ;-)
00266 
00267  */
00268 
00269 ULONG
00270 NTAPI
00271 CcpCountCacheSections(IN PNOCC_CACHE_MAP Map)
00272 {
00273     PLIST_ENTRY Entry;
00274     ULONG Count;
00275 
00276     for (Count = 0, Entry = Map->AssociatedBcb.Flink;
00277          Entry != &Map->AssociatedBcb;
00278          Entry = Entry->Flink, Count++);
00279 
00280     return Count;
00281 }
00282 
00283 BOOLEAN
00284 NTAPI
00285 CcUninitializeCacheMap(IN PFILE_OBJECT FileObject,
00286                        IN OPTIONAL PLARGE_INTEGER TruncateSize,
00287                        IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
00288 {
00289     BOOLEAN LastMap = FALSE;
00290     PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
00291     PNOCC_PRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
00292 
00293     DPRINT("Uninitializing file object for %wZ SectionObjectPointer %x\n",
00294            &FileObject->FileName,
00295            FileObject->SectionObjectPointer);
00296 
00297     ASSERT(UninitializeEvent == NULL);
00298 
00299     /* It may not be strictly necessary to flush here, but we do just for
00300        kicks. */
00301     if (Map)
00302         CcpFlushCache(Map, NULL, 0, NULL, FALSE);
00303 
00304     CcpLock();
00305     /* We have a private cache map, so we've been initialized and haven't been
00306      * uninitialized. */
00307     if (PrivateCacheMap)
00308     {
00309         ASSERT(!Map || Map == PrivateCacheMap->Map);
00310         ASSERT(PrivateCacheMap->FileObject == FileObject);
00311 
00312         RemoveEntryList(&PrivateCacheMap->ListEntry);
00313         /* That was the last private cache map.  It's time to delete all
00314            cache stripes and all aspects of caching on the file. */
00315         if (IsListEmpty(&PrivateCacheMap->Map->PrivateCacheMaps))
00316         {
00317             /* Get rid of all the cache stripes. */
00318             while (!IsListEmpty(&PrivateCacheMap->Map->AssociatedBcb))
00319             {
00320                 PNOCC_BCB Bcb = CONTAINING_RECORD(PrivateCacheMap->Map->AssociatedBcb.Flink,
00321                                                   NOCC_BCB,
00322                                                   ThisFileList);
00323 
00324                 DPRINT("Evicting cache stripe #%x\n", Bcb - CcCacheSections);
00325                 Bcb->RefCount = 1;
00326                 CcpDereferenceCache(Bcb - CcCacheSections, TRUE);
00327             }
00328             RemoveEntryList(&PrivateCacheMap->Map->Entry);
00329             ExFreePool(PrivateCacheMap->Map);
00330             FileObject->SectionObjectPointer->SharedCacheMap = NULL;
00331             LastMap = TRUE;
00332         }
00333         ObDereferenceObject(PrivateCacheMap->FileObject);
00334         FileObject->PrivateCacheMap = NULL;
00335         ExFreePool(PrivateCacheMap);
00336     }
00337     CcpUnlock();
00338 
00339     DPRINT("Uninit complete\n");
00340 
00341     /* The return from CcUninitializeCacheMap means that 'caching was stopped'. */
00342     return LastMap;
00343 }
00344 
00345 /*
00346 
00347 CcSetFileSizes is used to tell the cache manager that the file changed
00348 size.  In our case, we use the internal Mm method MmExtendCacheSection
00349 to notify Mm that our section potentially changed size, which may mean
00350 truncating off data.
00351 
00352  */
00353 VOID
00354 NTAPI
00355 CcSetFileSizes(IN PFILE_OBJECT FileObject,
00356                IN PCC_FILE_SIZES FileSizes)
00357 {
00358     PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
00359     PNOCC_BCB Bcb;
00360 
00361     if (!Map) return;
00362     Map->FileSizes = *FileSizes;
00363     Bcb = Map->AssociatedBcb.Flink == &Map->AssociatedBcb ?
00364         NULL : CONTAINING_RECORD(Map->AssociatedBcb.Flink, NOCC_BCB, ThisFileList);
00365     if (!Bcb) return;
00366     MmExtendCacheSection(Bcb->SectionObject, &FileSizes->FileSize, FALSE);
00367     DPRINT("FileSizes->FileSize %x\n", FileSizes->FileSize.LowPart);
00368     DPRINT("FileSizes->AllocationSize %x\n", FileSizes->AllocationSize.LowPart);
00369     DPRINT("FileSizes->ValidDataLength %x\n", FileSizes->ValidDataLength.LowPart);
00370 }
00371 
00372 BOOLEAN
00373 NTAPI
00374 CcGetFileSizes(IN PFILE_OBJECT FileObject,
00375                IN PCC_FILE_SIZES FileSizes)
00376 {
00377     PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap;
00378     if (!Map) return FALSE;
00379     *FileSizes = Map->FileSizes;
00380     return TRUE;
00381 }
00382 
00383 BOOLEAN
00384 NTAPI
00385 CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
00386                     IN OPTIONAL PLARGE_INTEGER FileOffset,
00387                     IN ULONG Length,
00388                     IN BOOLEAN UninitializeCacheMaps)
00389 {
00390     PNOCC_CACHE_MAP Map = (PNOCC_CACHE_MAP)SectionObjectPointer->SharedCacheMap;
00391     if (!Map) return TRUE;
00392     CcpFlushCache(Map, NULL, 0, NULL, TRUE);
00393     return TRUE;
00394 }
00395 
00396 VOID
00397 NTAPI
00398 CcSetDirtyPageThreshold(IN PFILE_OBJECT FileObject,
00399                         IN ULONG DirtyPageThreshold)
00400 {
00401     UNIMPLEMENTED;
00402     while (TRUE);
00403 }
00404 
00405 /*
00406 
00407 This could be implemented much more intelligently by mapping instances
00408 of a CoW zero page into the affected regions.  We just RtlZeroMemory
00409 for now.
00410 
00411 */
00412 BOOLEAN
00413 NTAPI
00414 CcZeroData(IN PFILE_OBJECT FileObject,
00415            IN PLARGE_INTEGER StartOffset,
00416            IN PLARGE_INTEGER EndOffset,
00417            IN BOOLEAN Wait)
00418 {
00419     PNOCC_BCB Bcb = NULL;
00420     PLIST_ENTRY ListEntry = NULL;
00421     LARGE_INTEGER LowerBound = *StartOffset;
00422     LARGE_INTEGER UpperBound = *EndOffset;
00423     LARGE_INTEGER Target, End;
00424     PVOID PinnedBcb, PinnedBuffer;
00425     PNOCC_CACHE_MAP Map = FileObject->SectionObjectPointer->SharedCacheMap;
00426 
00427     DPRINT("S %08x%08x E %08x%08x\n",
00428            StartOffset->u.HighPart,
00429            StartOffset->u.LowPart,
00430            EndOffset->u.HighPart,
00431            EndOffset->u.LowPart);
00432 
00433     if (!Map)
00434     {
00435         NTSTATUS Status;
00436         IO_STATUS_BLOCK IOSB;
00437         PCHAR ZeroBuf = ExAllocatePool(PagedPool, PAGE_SIZE);
00438         ULONG ToWrite;
00439 
00440         if (!ZeroBuf) RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00441         DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
00442         RtlZeroMemory(ZeroBuf, PAGE_SIZE);
00443 
00444         Target.QuadPart = PAGE_ROUND_DOWN(LowerBound.QuadPart);
00445         End.QuadPart = PAGE_ROUND_UP(UpperBound.QuadPart);
00446 
00447         // Handle leading page
00448         if (LowerBound.QuadPart != Target.QuadPart)
00449         {
00450             ToWrite = MIN(UpperBound.QuadPart - LowerBound.QuadPart,
00451                           (PAGE_SIZE - LowerBound.QuadPart) & (PAGE_SIZE - 1));
00452 
00453             DPRINT("Zero last half %08x%08x %x\n",
00454                    Target.u.HighPart,
00455                    Target.u.LowPart,
00456                    ToWrite);
00457 
00458             Status = MiSimpleRead(FileObject,
00459                                   &Target,
00460                                   ZeroBuf,
00461                                   PAGE_SIZE,
00462                                   TRUE,
00463                                   &IOSB);
00464 
00465             if (!NT_SUCCESS(Status))
00466             {
00467                 ExFreePool(ZeroBuf);
00468                 RtlRaiseStatus(Status);
00469             }
00470 
00471             DPRINT1("RtlZeroMemory(%x,%x)\n",
00472                     ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
00473                     ToWrite);
00474 
00475             RtlZeroMemory(ZeroBuf + LowerBound.QuadPart - Target.QuadPart,
00476                           ToWrite);
00477 
00478             Status = MiSimpleWrite(FileObject,
00479                                    &Target,
00480                                    ZeroBuf,
00481                                    MIN(PAGE_SIZE,
00482                                        UpperBound.QuadPart-Target.QuadPart),
00483                                    &IOSB);
00484 
00485             if (!NT_SUCCESS(Status))
00486             {
00487                 ExFreePool(ZeroBuf);
00488                 RtlRaiseStatus(Status);
00489             }
00490             Target.QuadPart += PAGE_SIZE;
00491         }
00492 
00493         DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, PAGE_SIZE);
00494         RtlZeroMemory(ZeroBuf, PAGE_SIZE);
00495 
00496         while (UpperBound.QuadPart - Target.QuadPart > PAGE_SIZE)
00497         {
00498             DPRINT("Zero full page %08x%08x\n",
00499                    Target.u.HighPart,
00500                    Target.u.LowPart);
00501 
00502             Status = MiSimpleWrite(FileObject,
00503                                    &Target,
00504                                    ZeroBuf,
00505                                    PAGE_SIZE,
00506                                    &IOSB);
00507 
00508             if (!NT_SUCCESS(Status))
00509             {
00510                 ExFreePool(ZeroBuf);
00511                 RtlRaiseStatus(Status);
00512             }
00513             Target.QuadPart += PAGE_SIZE;
00514         }
00515 
00516         if (UpperBound.QuadPart > Target.QuadPart)
00517         {
00518             ToWrite = UpperBound.QuadPart - Target.QuadPart;
00519             DPRINT("Zero first half %08x%08x %x\n",
00520                    Target.u.HighPart,
00521                    Target.u.LowPart,
00522                    ToWrite);
00523 
00524             Status = MiSimpleRead(FileObject,
00525                                   &Target,
00526                                   ZeroBuf,
00527                                   PAGE_SIZE,
00528                                   TRUE,
00529                                   &IOSB);
00530 
00531             if (!NT_SUCCESS(Status))
00532             {
00533                 ExFreePool(ZeroBuf);
00534                 RtlRaiseStatus(Status);
00535             }
00536             DPRINT1("RtlZeroMemory(%x,%x)\n", ZeroBuf, ToWrite);
00537             RtlZeroMemory(ZeroBuf, ToWrite);
00538             Status = MiSimpleWrite(FileObject,
00539                                    &Target,
00540                                    ZeroBuf,
00541                                    MIN(PAGE_SIZE,
00542                                        UpperBound.QuadPart-Target.QuadPart),
00543                                    &IOSB);
00544             if (!NT_SUCCESS(Status))
00545             {
00546                 ExFreePool(ZeroBuf);
00547                 RtlRaiseStatus(Status);
00548             }
00549             Target.QuadPart += PAGE_SIZE;
00550         }
00551 
00552         ExFreePool(ZeroBuf);
00553         return TRUE;
00554     }
00555 
00556     CcpLock();
00557     ListEntry = Map->AssociatedBcb.Flink;
00558 
00559     while (ListEntry != &Map->AssociatedBcb)
00560     {
00561         Bcb = CONTAINING_RECORD(ListEntry, NOCC_BCB, ThisFileList);
00562         CcpReferenceCache(Bcb - CcCacheSections);
00563 
00564         if (Bcb->FileOffset.QuadPart + Bcb->Length >= LowerBound.QuadPart &&
00565             Bcb->FileOffset.QuadPart < UpperBound.QuadPart)
00566         {
00567             DPRINT("Bcb #%x (@%08x%08x)\n",
00568                    Bcb - CcCacheSections,
00569                    Bcb->FileOffset.u.HighPart,
00570                    Bcb->FileOffset.u.LowPart);
00571 
00572             Target.QuadPart = MAX(Bcb->FileOffset.QuadPart,
00573                                   LowerBound.QuadPart);
00574 
00575             End.QuadPart = MIN(Map->FileSizes.ValidDataLength.QuadPart,
00576                                UpperBound.QuadPart);
00577 
00578             End.QuadPart = MIN(End.QuadPart,
00579                                Bcb->FileOffset.QuadPart + Bcb->Length);
00580 
00581             CcpUnlock();
00582 
00583             if (!CcPreparePinWrite(FileObject,
00584                                    &Target,
00585                                    End.QuadPart - Target.QuadPart,
00586                                    TRUE,
00587                                    Wait,
00588                                    &PinnedBcb,
00589                                    &PinnedBuffer))
00590             {
00591                 return FALSE;
00592             }
00593 
00594             ASSERT(PinnedBcb == Bcb);
00595 
00596             CcpLock();
00597             ListEntry = ListEntry->Flink;
00598             /* Return from pin state */
00599             CcpUnpinData(PinnedBcb, TRUE);
00600         }
00601 
00602         CcpUnpinData(Bcb, TRUE);
00603     }
00604 
00605     CcpUnlock();
00606 
00607     return TRUE;
00608 }
00609 
00610 PFILE_OBJECT
00611 NTAPI
00612 CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointer)
00613 {
00614     PFILE_OBJECT Result = NULL;
00615     PNOCC_CACHE_MAP Map = SectionObjectPointer->SharedCacheMap;
00616     CcpLock();
00617     if (!IsListEmpty(&Map->AssociatedBcb))
00618     {
00619         PNOCC_BCB Bcb = CONTAINING_RECORD(Map->AssociatedBcb.Flink,
00620                                           NOCC_BCB,
00621                                           ThisFileList);
00622 
00623         Result = MmGetFileObjectForSection((PROS_SECTION_OBJECT)Bcb->SectionObject);
00624     }
00625     CcpUnlock();
00626     return Result;
00627 }
00628 
00629 PFILE_OBJECT
00630 NTAPI
00631 CcGetFileObjectFromBcb(PVOID Bcb)
00632 {
00633     PNOCC_BCB RealBcb = (PNOCC_BCB)Bcb;
00634     DPRINT("BCB #%x\n", RealBcb - CcCacheSections);
00635     return MmGetFileObjectForSection((PROS_SECTION_OBJECT)RealBcb->SectionObject);
00636 }
00637 
00638 /* EOF */

Generated on Sat May 26 2012 04:35:55 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.