1 #pragma once 2 3 // 4 // Define this if you want debugging support 5 // 6 #define _CC_DEBUG_ 0x00 7 8 // 9 // These define the Debug Masks Supported 10 // 11 #define CC_API_DEBUG 0x01 12 13 // 14 // Debug/Tracing support 15 // 16 #if _CC_DEBUG_ 17 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented 18 #define CCTRACE(x, ...) \ 19 { \ 20 DbgPrintEx("%s [%.16s] - ", \ 21 __FUNCTION__, \ 22 PsGetCurrentProcess()->ImageFileName); \ 23 DbgPrintEx(__VA_ARGS__); \ 24 } 25 #else 26 #define CCTRACE(x, ...) \ 27 if (x & CcRosTraceLevel) \ 28 { \ 29 DbgPrint("%s [%.16s] - ", \ 30 __FUNCTION__, \ 31 PsGetCurrentProcess()->ImageFileName); \ 32 DbgPrint(__VA_ARGS__); \ 33 } 34 #endif 35 #else 36 #define CCTRACE(x, fmt, ...) DPRINT(fmt, ##__VA_ARGS__) 37 #endif 38 39 // 40 // Global Cc Data 41 // 42 extern ULONG CcRosTraceLevel; 43 extern LIST_ENTRY DirtyVacbListHead; 44 extern ULONG CcDirtyPageThreshold; 45 extern ULONG CcTotalDirtyPages; 46 extern LIST_ENTRY CcDeferredWrites; 47 extern KSPIN_LOCK CcDeferredWriteSpinLock; 48 extern ULONG CcNumberWorkerThreads; 49 extern LIST_ENTRY CcIdleWorkerThreadList; 50 extern LIST_ENTRY CcExpressWorkQueue; 51 extern LIST_ENTRY CcRegularWorkQueue; 52 extern LIST_ENTRY CcPostTickWorkQueue; 53 extern NPAGED_LOOKASIDE_LIST CcTwilightLookasideList; 54 extern LARGE_INTEGER CcIdleDelay; 55 56 // 57 // Counters 58 // 59 extern ULONG CcLazyWritePages; 60 extern ULONG CcLazyWriteIos; 61 extern ULONG CcMapDataWait; 62 extern ULONG CcMapDataNoWait; 63 extern ULONG CcPinReadWait; 64 extern ULONG CcPinReadNoWait; 65 extern ULONG CcDataPages; 66 extern ULONG CcDataFlushes; 67 68 typedef struct _PF_SCENARIO_ID 69 { 70 WCHAR ScenName[30]; 71 ULONG HashId; 72 } PF_SCENARIO_ID, *PPF_SCENARIO_ID; 73 74 typedef struct _PF_LOG_ENTRY 75 { 76 ULONG FileOffset:30; 77 ULONG Type:2; 78 union 79 { 80 ULONG FileKey; 81 ULONG FileSequenceNumber; 82 }; 83 } PF_LOG_ENTRY, *PPF_LOG_ENTRY; 84 85 typedef struct _PFSN_LOG_ENTRIES 86 { 87 LIST_ENTRY TraceBuffersLink; 88 LONG NumEntries; 89 LONG MaxEntries; 90 PF_LOG_ENTRY Entries[ANYSIZE_ARRAY]; 91 } PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES; 92 93 typedef struct _PF_SECTION_INFO 94 { 95 ULONG FileKey; 96 ULONG FileSequenceNumber; 97 ULONG FileIdLow; 98 ULONG FileIdHigh; 99 } PF_SECTION_INFO, *PPF_SECTION_INFO; 100 101 typedef struct _PF_TRACE_HEADER 102 { 103 ULONG Version; 104 ULONG MagicNumber; 105 ULONG Size; 106 PF_SCENARIO_ID ScenarioId; 107 ULONG ScenarioType; // PF_SCENARIO_TYPE 108 ULONG EventEntryIdxs[8]; 109 ULONG NumEventEntryIdxs; 110 ULONG TraceBufferOffset; 111 ULONG NumEntries; 112 ULONG SectionInfoOffset; 113 ULONG NumSections; 114 ULONG FaultsPerPeriod[10]; 115 LARGE_INTEGER LaunchTime; 116 ULONGLONG Reserved[5]; 117 } PF_TRACE_HEADER, *PPF_TRACE_HEADER; 118 119 typedef struct _PFSN_TRACE_DUMP 120 { 121 LIST_ENTRY CompletedTracesLink; 122 PF_TRACE_HEADER Trace; 123 } PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP; 124 125 typedef struct _PFSN_TRACE_HEADER 126 { 127 ULONG Magic; 128 LIST_ENTRY ActiveTracesLink; 129 PF_SCENARIO_ID ScenarioId; 130 ULONG ScenarioType; // PF_SCENARIO_TYPE 131 ULONG EventEntryIdxs[8]; 132 ULONG NumEventEntryIdxs; 133 PPFSN_LOG_ENTRIES CurrentTraceBuffer; 134 LIST_ENTRY TraceBuffersList; 135 ULONG NumTraceBuffers; 136 KSPIN_LOCK TraceBufferSpinLock; 137 KTIMER TraceTimer; 138 LARGE_INTEGER TraceTimerPeriod; 139 KDPC TraceTimerDpc; 140 KSPIN_LOCK TraceTimerSpinLock; 141 ULONG FaultsPerPeriod[10]; 142 LONG LastNumFaults; 143 LONG CurPeriod; 144 LONG NumFaults; 145 LONG MaxFaults; 146 PEPROCESS Process; 147 EX_RUNDOWN_REF RefCount; 148 WORK_QUEUE_ITEM EndTraceWorkItem; 149 LONG EndTraceCalled; 150 PPFSN_TRACE_DUMP TraceDump; 151 NTSTATUS TraceDumpStatus; 152 LARGE_INTEGER LaunchTime; 153 PPF_SECTION_INFO SectionInfo; 154 ULONG SectionInfoCount; 155 } PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER; 156 157 typedef struct _PFSN_PREFETCHER_GLOBALS 158 { 159 LIST_ENTRY ActiveTraces; 160 KSPIN_LOCK ActiveTracesLock; 161 PPFSN_TRACE_HEADER SystemWideTrace; 162 LIST_ENTRY CompletedTraces; 163 FAST_MUTEX CompletedTracesLock; 164 LONG NumCompletedTraces; 165 PKEVENT CompletedTracesEvent; 166 LONG ActivePrefetches; 167 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS; 168 169 typedef struct _ROS_SHARED_CACHE_MAP 170 { 171 CSHORT NodeTypeCode; 172 CSHORT NodeByteSize; 173 ULONG OpenCount; 174 LARGE_INTEGER FileSize; 175 LARGE_INTEGER SectionSize; 176 PFILE_OBJECT FileObject; 177 ULONG DirtyPages; 178 LIST_ENTRY SharedCacheMapLinks; 179 ULONG Flags; 180 PCACHE_MANAGER_CALLBACKS Callbacks; 181 PVOID LazyWriteContext; 182 LIST_ENTRY PrivateList; 183 ULONG DirtyPageThreshold; 184 PRIVATE_CACHE_MAP PrivateCacheMap; 185 186 /* ROS specific */ 187 LIST_ENTRY CacheMapVacbListHead; 188 ULONG TimeStamp; 189 BOOLEAN PinAccess; 190 KSPIN_LOCK CacheMapLock; 191 #if DBG 192 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ 193 #endif 194 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP; 195 196 #define READAHEAD_DISABLED 0x1 197 #define WRITEBEHIND_DISABLED 0x2 198 199 typedef struct _ROS_VACB 200 { 201 /* Base address of the region where the view's data is mapped. */ 202 PVOID BaseAddress; 203 /* Memory area representing the region where the view's data is mapped. */ 204 struct _MEMORY_AREA* MemoryArea; 205 /* Are the contents of the view valid. */ 206 BOOLEAN Valid; 207 /* Are the contents of the view newer than those on disk. */ 208 BOOLEAN Dirty; 209 /* Page out in progress */ 210 BOOLEAN PageOut; 211 ULONG MappedCount; 212 /* Entry in the list of VACBs for this shared cache map. */ 213 LIST_ENTRY CacheMapVacbListEntry; 214 /* Entry in the list of VACBs which are dirty. */ 215 LIST_ENTRY DirtyVacbListEntry; 216 /* Entry in the list of VACBs. */ 217 LIST_ENTRY VacbLruListEntry; 218 /* Offset in the file which this view maps. */ 219 LARGE_INTEGER FileOffset; 220 /* Mutex */ 221 KMUTEX Mutex; 222 /* Number of references. */ 223 volatile ULONG ReferenceCount; 224 /* How many times was it pinned? */ 225 _Guarded_by_(Mutex) 226 LONG PinCount; 227 /* Pointer to the shared cache map for the file which this view maps data for. */ 228 PROS_SHARED_CACHE_MAP SharedCacheMap; 229 /* Pointer to the next VACB in a chain. */ 230 } ROS_VACB, *PROS_VACB; 231 232 typedef struct _INTERNAL_BCB 233 { 234 /* Lock */ 235 ERESOURCE Lock; 236 PUBLIC_BCB PFCB; 237 PROS_VACB Vacb; 238 BOOLEAN Dirty; 239 BOOLEAN Pinned; 240 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */ 241 } INTERNAL_BCB, *PINTERNAL_BCB; 242 243 typedef struct _LAZY_WRITER 244 { 245 LIST_ENTRY WorkQueue; 246 KDPC ScanDpc; 247 KTIMER ScanTimer; 248 BOOLEAN ScanActive; 249 BOOLEAN OtherWork; 250 BOOLEAN PendingTeardown; 251 } LAZY_WRITER, *PLAZY_WRITER; 252 253 typedef struct _WORK_QUEUE_ENTRY 254 { 255 LIST_ENTRY WorkQueueLinks; 256 union 257 { 258 struct 259 { 260 FILE_OBJECT *FileObject; 261 } Read; 262 struct 263 { 264 SHARED_CACHE_MAP *SharedCacheMap; 265 } Write; 266 struct 267 { 268 KEVENT *Event; 269 } Event; 270 struct 271 { 272 unsigned long Reason; 273 } Notification; 274 } Parameters; 275 unsigned char Function; 276 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY; 277 278 typedef enum _WORK_QUEUE_FUNCTIONS 279 { 280 ReadAhead = 1, 281 WriteBehind = 2, 282 LazyWrite = 3, 283 SetDone = 4, 284 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS; 285 286 extern LAZY_WRITER LazyWriter; 287 288 #define NODE_TYPE_DEFERRED_WRITE 0x02FC 289 #define NODE_TYPE_PRIVATE_MAP 0x02FE 290 #define NODE_TYPE_SHARED_MAP 0x02FF 291 292 VOID 293 NTAPI 294 CcPfInitializePrefetcher( 295 VOID 296 ); 297 298 VOID 299 NTAPI 300 CcMdlReadComplete2( 301 IN PFILE_OBJECT FileObject, 302 IN PMDL MemoryDescriptorList 303 ); 304 305 VOID 306 NTAPI 307 CcMdlWriteComplete2( 308 IN PFILE_OBJECT FileObject, 309 IN PLARGE_INTEGER FileOffset, 310 IN PMDL MdlChain 311 ); 312 313 NTSTATUS 314 NTAPI 315 CcRosFlushVacb(PROS_VACB Vacb); 316 317 NTSTATUS 318 NTAPI 319 CcRosGetVacb( 320 PROS_SHARED_CACHE_MAP SharedCacheMap, 321 LONGLONG FileOffset, 322 PLONGLONG BaseOffset, 323 PVOID *BaseAddress, 324 PBOOLEAN UptoDate, 325 PROS_VACB *Vacb 326 ); 327 328 VOID 329 NTAPI 330 CcInitView(VOID); 331 332 VOID 333 NTAPI 334 CcShutdownLazyWriter(VOID); 335 336 NTSTATUS 337 NTAPI 338 CcReadVirtualAddress(PROS_VACB Vacb); 339 340 NTSTATUS 341 NTAPI 342 CcWriteVirtualAddress(PROS_VACB Vacb); 343 344 BOOLEAN 345 NTAPI 346 CcInitializeCacheManager(VOID); 347 348 NTSTATUS 349 NTAPI 350 CcRosUnmapVacb( 351 PROS_SHARED_CACHE_MAP SharedCacheMap, 352 LONGLONG FileOffset, 353 BOOLEAN NowDirty 354 ); 355 356 PROS_VACB 357 NTAPI 358 CcRosLookupVacb( 359 PROS_SHARED_CACHE_MAP SharedCacheMap, 360 LONGLONG FileOffset 361 ); 362 363 VOID 364 NTAPI 365 CcInitCacheZeroPage(VOID); 366 367 NTSTATUS 368 NTAPI 369 CcRosMarkDirtyFile( 370 PROS_SHARED_CACHE_MAP SharedCacheMap, 371 LONGLONG FileOffset 372 ); 373 374 VOID 375 NTAPI 376 CcRosMarkDirtyVacb( 377 PROS_VACB Vacb); 378 379 VOID 380 NTAPI 381 CcRosUnmarkDirtyVacb( 382 PROS_VACB Vacb, 383 BOOLEAN LockViews); 384 385 NTSTATUS 386 NTAPI 387 CcRosFlushDirtyPages( 388 ULONG Target, 389 PULONG Count, 390 BOOLEAN Wait, 391 BOOLEAN CalledFromLazy 392 ); 393 394 VOID 395 NTAPI 396 CcRosDereferenceCache(PFILE_OBJECT FileObject); 397 398 VOID 399 NTAPI 400 CcRosReferenceCache(PFILE_OBJECT FileObject); 401 402 VOID 403 NTAPI 404 CcRosRemoveIfClosed(PSECTION_OBJECT_POINTERS SectionObjectPointer); 405 406 NTSTATUS 407 NTAPI 408 CcRosReleaseVacb( 409 PROS_SHARED_CACHE_MAP SharedCacheMap, 410 PROS_VACB Vacb, 411 BOOLEAN Valid, 412 BOOLEAN Dirty, 413 BOOLEAN Mapped 414 ); 415 416 NTSTATUS 417 NTAPI 418 CcRosRequestVacb( 419 PROS_SHARED_CACHE_MAP SharedCacheMap, 420 LONGLONG FileOffset, 421 PVOID* BaseAddress, 422 PBOOLEAN UptoDate, 423 PROS_VACB *Vacb 424 ); 425 426 NTSTATUS 427 NTAPI 428 CcRosInitializeFileCache( 429 PFILE_OBJECT FileObject, 430 PCC_FILE_SIZES FileSizes, 431 BOOLEAN PinAccess, 432 PCACHE_MANAGER_CALLBACKS CallBacks, 433 PVOID LazyWriterContext 434 ); 435 436 NTSTATUS 437 NTAPI 438 CcRosReleaseFileCache( 439 PFILE_OBJECT FileObject 440 ); 441 442 VOID 443 NTAPI 444 CcShutdownSystem(VOID); 445 446 VOID 447 NTAPI 448 CcWorkerThread(PVOID Parameter); 449 450 VOID 451 NTAPI 452 CcScanDpc( 453 PKDPC Dpc, 454 PVOID DeferredContext, 455 PVOID SystemArgument1, 456 PVOID SystemArgument2); 457 458 VOID 459 CcScheduleLazyWriteScan(BOOLEAN NoDelay); 460 461 VOID 462 CcPostDeferredWrites(VOID); 463 464 VOID 465 CcPostWorkQueue( 466 IN PWORK_QUEUE_ENTRY WorkItem, 467 IN PLIST_ENTRY WorkQueue); 468 469 VOID 470 CcPerformReadAhead( 471 IN PFILE_OBJECT FileObject); 472 473 FORCEINLINE 474 NTSTATUS 475 CcRosAcquireVacbLock( 476 _Inout_ PROS_VACB Vacb, 477 _In_ PLARGE_INTEGER Timeout) 478 { 479 NTSTATUS Status; 480 Status = KeWaitForSingleObject(&Vacb->Mutex, 481 Executive, 482 KernelMode, 483 FALSE, 484 Timeout); 485 return Status; 486 } 487 488 FORCEINLINE 489 VOID 490 CcRosReleaseVacbLock( 491 _Inout_ PROS_VACB Vacb) 492 { 493 KeReleaseMutex(&Vacb->Mutex, FALSE); 494 } 495 496 FORCEINLINE 497 BOOLEAN 498 DoRangesIntersect( 499 _In_ LONGLONG Offset1, 500 _In_ LONGLONG Length1, 501 _In_ LONGLONG Offset2, 502 _In_ LONGLONG Length2) 503 { 504 if (Offset1 + Length1 <= Offset2) 505 return FALSE; 506 if (Offset2 + Length2 <= Offset1) 507 return FALSE; 508 return TRUE; 509 } 510 511 FORCEINLINE 512 BOOLEAN 513 IsPointInRange( 514 _In_ LONGLONG Offset1, 515 _In_ LONGLONG Length1, 516 _In_ LONGLONG Point) 517 { 518 return DoRangesIntersect(Offset1, Length1, Point, 1); 519 } 520 521 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C) 522 523 #if DBG 524 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__) 525 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__) 526 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__) 527 528 ULONG 529 CcRosVacbIncRefCount_( 530 PROS_VACB vacb, 531 PCSTR file, 532 INT line); 533 534 ULONG 535 CcRosVacbDecRefCount_( 536 PROS_VACB vacb, 537 PCSTR file, 538 INT line); 539 540 ULONG 541 CcRosVacbGetRefCount_( 542 PROS_VACB vacb, 543 PCSTR file, 544 INT line); 545 546 #else 547 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount) 548 #define CcRosVacbDecRefCount(vacb) InterlockedDecrement((PLONG)&(vacb)->ReferenceCount) 549 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0) 550 #endif 551