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 CcPinMappedDataCount; 66 extern ULONG CcDataPages; 67 extern ULONG CcDataFlushes; 68 69 typedef struct _PF_SCENARIO_ID 70 { 71 WCHAR ScenName[30]; 72 ULONG HashId; 73 } PF_SCENARIO_ID, *PPF_SCENARIO_ID; 74 75 typedef struct _PF_LOG_ENTRY 76 { 77 ULONG FileOffset:30; 78 ULONG Type:2; 79 union 80 { 81 ULONG FileKey; 82 ULONG FileSequenceNumber; 83 }; 84 } PF_LOG_ENTRY, *PPF_LOG_ENTRY; 85 86 typedef struct _PFSN_LOG_ENTRIES 87 { 88 LIST_ENTRY TraceBuffersLink; 89 LONG NumEntries; 90 LONG MaxEntries; 91 PF_LOG_ENTRY Entries[ANYSIZE_ARRAY]; 92 } PFSN_LOG_ENTRIES, *PPFSN_LOG_ENTRIES; 93 94 typedef struct _PF_SECTION_INFO 95 { 96 ULONG FileKey; 97 ULONG FileSequenceNumber; 98 ULONG FileIdLow; 99 ULONG FileIdHigh; 100 } PF_SECTION_INFO, *PPF_SECTION_INFO; 101 102 typedef struct _PF_TRACE_HEADER 103 { 104 ULONG Version; 105 ULONG MagicNumber; 106 ULONG Size; 107 PF_SCENARIO_ID ScenarioId; 108 ULONG ScenarioType; // PF_SCENARIO_TYPE 109 ULONG EventEntryIdxs[8]; 110 ULONG NumEventEntryIdxs; 111 ULONG TraceBufferOffset; 112 ULONG NumEntries; 113 ULONG SectionInfoOffset; 114 ULONG NumSections; 115 ULONG FaultsPerPeriod[10]; 116 LARGE_INTEGER LaunchTime; 117 ULONGLONG Reserved[5]; 118 } PF_TRACE_HEADER, *PPF_TRACE_HEADER; 119 120 typedef struct _PFSN_TRACE_DUMP 121 { 122 LIST_ENTRY CompletedTracesLink; 123 PF_TRACE_HEADER Trace; 124 } PFSN_TRACE_DUMP, *PPFSN_TRACE_DUMP; 125 126 typedef struct _PFSN_TRACE_HEADER 127 { 128 ULONG Magic; 129 LIST_ENTRY ActiveTracesLink; 130 PF_SCENARIO_ID ScenarioId; 131 ULONG ScenarioType; // PF_SCENARIO_TYPE 132 ULONG EventEntryIdxs[8]; 133 ULONG NumEventEntryIdxs; 134 PPFSN_LOG_ENTRIES CurrentTraceBuffer; 135 LIST_ENTRY TraceBuffersList; 136 ULONG NumTraceBuffers; 137 KSPIN_LOCK TraceBufferSpinLock; 138 KTIMER TraceTimer; 139 LARGE_INTEGER TraceTimerPeriod; 140 KDPC TraceTimerDpc; 141 KSPIN_LOCK TraceTimerSpinLock; 142 ULONG FaultsPerPeriod[10]; 143 LONG LastNumFaults; 144 LONG CurPeriod; 145 LONG NumFaults; 146 LONG MaxFaults; 147 PEPROCESS Process; 148 EX_RUNDOWN_REF RefCount; 149 WORK_QUEUE_ITEM EndTraceWorkItem; 150 LONG EndTraceCalled; 151 PPFSN_TRACE_DUMP TraceDump; 152 NTSTATUS TraceDumpStatus; 153 LARGE_INTEGER LaunchTime; 154 PPF_SECTION_INFO SectionInfo; 155 ULONG SectionInfoCount; 156 } PFSN_TRACE_HEADER, *PPFSN_TRACE_HEADER; 157 158 typedef struct _PFSN_PREFETCHER_GLOBALS 159 { 160 LIST_ENTRY ActiveTraces; 161 KSPIN_LOCK ActiveTracesLock; 162 PPFSN_TRACE_HEADER SystemWideTrace; 163 LIST_ENTRY CompletedTraces; 164 FAST_MUTEX CompletedTracesLock; 165 LONG NumCompletedTraces; 166 PKEVENT CompletedTracesEvent; 167 LONG ActivePrefetches; 168 } PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS; 169 170 typedef struct _ROS_SHARED_CACHE_MAP 171 { 172 CSHORT NodeTypeCode; 173 CSHORT NodeByteSize; 174 ULONG OpenCount; 175 LARGE_INTEGER FileSize; 176 LIST_ENTRY BcbList; 177 LARGE_INTEGER SectionSize; 178 PFILE_OBJECT FileObject; 179 ULONG DirtyPages; 180 LIST_ENTRY SharedCacheMapLinks; 181 ULONG Flags; 182 PCACHE_MANAGER_CALLBACKS Callbacks; 183 PVOID LazyWriteContext; 184 LIST_ENTRY PrivateList; 185 ULONG DirtyPageThreshold; 186 KSPIN_LOCK BcbSpinLock; 187 PRIVATE_CACHE_MAP PrivateCacheMap; 188 189 /* ROS specific */ 190 LIST_ENTRY CacheMapVacbListHead; 191 BOOLEAN PinAccess; 192 KSPIN_LOCK CacheMapLock; 193 #if DBG 194 BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ 195 #endif 196 } ROS_SHARED_CACHE_MAP, *PROS_SHARED_CACHE_MAP; 197 198 #define READAHEAD_DISABLED 0x1 199 #define WRITEBEHIND_DISABLED 0x2 200 201 typedef struct _ROS_VACB 202 { 203 /* Base address of the region where the view's data is mapped. */ 204 PVOID BaseAddress; 205 /* Memory area representing the region where the view's data is mapped. */ 206 struct _MEMORY_AREA* MemoryArea; 207 /* Are the contents of the view valid. */ 208 BOOLEAN Valid; 209 /* Are the contents of the view newer than those on disk. */ 210 BOOLEAN Dirty; 211 /* Page out in progress */ 212 BOOLEAN PageOut; 213 ULONG MappedCount; 214 /* Entry in the list of VACBs for this shared cache map. */ 215 LIST_ENTRY CacheMapVacbListEntry; 216 /* Entry in the list of VACBs which are dirty. */ 217 LIST_ENTRY DirtyVacbListEntry; 218 /* Entry in the list of VACBs. */ 219 LIST_ENTRY VacbLruListEntry; 220 /* Offset in the file which this view maps. */ 221 LARGE_INTEGER FileOffset; 222 /* Number of references. */ 223 volatile ULONG ReferenceCount; 224 /* Pointer to the shared cache map for the file which this view maps data for. */ 225 PROS_SHARED_CACHE_MAP SharedCacheMap; 226 /* Pointer to the next VACB in a chain. */ 227 } ROS_VACB, *PROS_VACB; 228 229 typedef struct _INTERNAL_BCB 230 { 231 /* Lock */ 232 ERESOURCE Lock; 233 PUBLIC_BCB PFCB; 234 PROS_VACB Vacb; 235 ULONG PinCount; 236 CSHORT RefCount; /* (At offset 0x34 on WinNT4) */ 237 LIST_ENTRY BcbEntry; 238 } INTERNAL_BCB, *PINTERNAL_BCB; 239 240 typedef struct _LAZY_WRITER 241 { 242 LIST_ENTRY WorkQueue; 243 KDPC ScanDpc; 244 KTIMER ScanTimer; 245 BOOLEAN ScanActive; 246 BOOLEAN OtherWork; 247 BOOLEAN PendingTeardown; 248 } LAZY_WRITER, *PLAZY_WRITER; 249 250 typedef struct _WORK_QUEUE_ENTRY 251 { 252 LIST_ENTRY WorkQueueLinks; 253 union 254 { 255 struct 256 { 257 FILE_OBJECT *FileObject; 258 } Read; 259 struct 260 { 261 SHARED_CACHE_MAP *SharedCacheMap; 262 } Write; 263 struct 264 { 265 KEVENT *Event; 266 } Event; 267 struct 268 { 269 unsigned long Reason; 270 } Notification; 271 } Parameters; 272 unsigned char Function; 273 } WORK_QUEUE_ENTRY, *PWORK_QUEUE_ENTRY; 274 275 typedef enum _WORK_QUEUE_FUNCTIONS 276 { 277 ReadAhead = 1, 278 WriteBehind = 2, 279 LazyScan = 3, 280 SetDone = 4, 281 } WORK_QUEUE_FUNCTIONS, *PWORK_QUEUE_FUNCTIONS; 282 283 extern LAZY_WRITER LazyWriter; 284 285 #define NODE_TYPE_DEFERRED_WRITE 0x02FC 286 #define NODE_TYPE_PRIVATE_MAP 0x02FE 287 #define NODE_TYPE_SHARED_MAP 0x02FF 288 289 INIT_FUNCTION 290 VOID 291 NTAPI 292 CcPfInitializePrefetcher( 293 VOID 294 ); 295 296 VOID 297 NTAPI 298 CcMdlReadComplete2( 299 IN PFILE_OBJECT FileObject, 300 IN PMDL MemoryDescriptorList 301 ); 302 303 VOID 304 NTAPI 305 CcMdlWriteComplete2( 306 IN PFILE_OBJECT FileObject, 307 IN PLARGE_INTEGER FileOffset, 308 IN PMDL MdlChain 309 ); 310 311 NTSTATUS 312 NTAPI 313 CcRosFlushVacb(PROS_VACB Vacb); 314 315 NTSTATUS 316 NTAPI 317 CcRosGetVacb( 318 PROS_SHARED_CACHE_MAP SharedCacheMap, 319 LONGLONG FileOffset, 320 PLONGLONG BaseOffset, 321 PVOID *BaseAddress, 322 PBOOLEAN UptoDate, 323 PROS_VACB *Vacb 324 ); 325 326 INIT_FUNCTION 327 VOID 328 NTAPI 329 CcInitView(VOID); 330 331 VOID 332 NTAPI 333 CcShutdownLazyWriter(VOID); 334 335 NTSTATUS 336 NTAPI 337 CcReadVirtualAddress(PROS_VACB Vacb); 338 339 NTSTATUS 340 NTAPI 341 CcWriteVirtualAddress(PROS_VACB Vacb); 342 343 INIT_FUNCTION 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 NTSTATUS 474 CcRosInternalFreeVacb( 475 IN PROS_VACB Vacb); 476 477 FORCEINLINE 478 BOOLEAN 479 DoRangesIntersect( 480 _In_ LONGLONG Offset1, 481 _In_ LONGLONG Length1, 482 _In_ LONGLONG Offset2, 483 _In_ LONGLONG Length2) 484 { 485 if (Offset1 + Length1 <= Offset2) 486 return FALSE; 487 if (Offset2 + Length2 <= Offset1) 488 return FALSE; 489 return TRUE; 490 } 491 492 FORCEINLINE 493 BOOLEAN 494 IsPointInRange( 495 _In_ LONGLONG Offset1, 496 _In_ LONGLONG Length1, 497 _In_ LONGLONG Point) 498 { 499 return DoRangesIntersect(Offset1, Length1, Point, 1); 500 } 501 502 #define CcBugCheck(A, B, C) KeBugCheckEx(CACHE_MANAGER, BugCheckFileId | ((ULONG)(__LINE__)), A, B, C) 503 504 #if DBG 505 #define CcRosVacbIncRefCount(vacb) CcRosVacbIncRefCount_(vacb,__FILE__,__LINE__) 506 #define CcRosVacbDecRefCount(vacb) CcRosVacbDecRefCount_(vacb,__FILE__,__LINE__) 507 #define CcRosVacbGetRefCount(vacb) CcRosVacbGetRefCount_(vacb,__FILE__,__LINE__) 508 509 ULONG 510 CcRosVacbIncRefCount_( 511 PROS_VACB vacb, 512 PCSTR file, 513 INT line); 514 515 ULONG 516 CcRosVacbDecRefCount_( 517 PROS_VACB vacb, 518 PCSTR file, 519 INT line); 520 521 ULONG 522 CcRosVacbGetRefCount_( 523 PROS_VACB vacb, 524 PCSTR file, 525 INT line); 526 527 #else 528 #define CcRosVacbIncRefCount(vacb) InterlockedIncrement((PLONG)&(vacb)->ReferenceCount) 529 FORCEINLINE 530 ULONG 531 CcRosVacbDecRefCount( 532 PROS_VACB vacb) 533 { 534 ULONG Refs; 535 536 Refs = InterlockedDecrement((PLONG)&vacb->ReferenceCount); 537 if (Refs == 0) 538 { 539 CcRosInternalFreeVacb(vacb); 540 } 541 return Refs; 542 } 543 #define CcRosVacbGetRefCount(vacb) InterlockedCompareExchange((PLONG)&(vacb)->ReferenceCount, 0, 0) 544 #endif 545