+sub IRP_MJ_READ_leave()
+{
+ # toplevel IRP_MJ_READ has no requirements
+ return if 0==@$EnterLeave;
+ my @stack=map({ $_->{"by"}=~/^IRP_MJ_/ ? () : $_ } @$EnterLeave);
+ my $opObject=$stack[0] if 1==@stack;
+ warn "IRP_MJ_READ not the expected function stack"
+ ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")"
+ if !($opObject->{"by"} eq "CcMapData"
+ || $opObject->{"by"} eq "CcCopyRead"
+ || $opObject->{"by"} eq "CcMdlRead"
+ || $opObject->{"by"} eq "CcPinRead");
+ if ($opObject->{"by"} eq "CcMdlRead") {
+ do { warn "Length $_ not divisible by 0x1000" if eval($_)%0x1000; } for ($Object->{"READ"}{"Length"});
+ }
+ else {
+ do { warn "Length $_ not 0x1000" if eval($_)!=0x1000; } for ($Object->{"READ"}{"Length"});
+ }
+ my $SharedCacheMap=$Object->{"data"}[0]{"SharedCacheMap"};
+ return if !(my $CObject=CObject $SharedCacheMap);
+ for my $reloffs (0..eval($Object->{"READ"}{"Length"})/0x1000-1) {
+ my $ByteOffset=tohex(eval($Object->{"READ"}{"ByteOffset"})+$reloffs*0x1000);
+ # Do not: warn "Reading ByteOffset $ByteOffset into SharedCacheMap $SharedCacheMap twice"
+ # if $CObject->{"in_memory"}{$ByteOffset};
+ # as it may be still cached there as Cache Manager is not forced to drop it.
+ $CObject->{"in_memory"}{$ByteOffset}=1;
+# warn "MARK: SharedCacheMap ".$CObject->{"SharedCacheMap"}." FileOffset $ByteOffset";
+ }
+}
+
+sub CcPurgeCacheSection($$$$$)
+{
+my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length,$UninitializeCacheMaps)=@_;
+
+ return if !(my $CObject=CObject $SharedCacheMap);
+ warn "Unexpected UninitializeCacheMaps $UninitializeCacheMaps" if $UninitializeCacheMaps ne "0";
+ my $all=($FileOffset eq "0x".("F"x8) && !eval $Length);
+ warn "Not yet implemented ranged CcPurgeCacheSection()" if !$all;
+ do { warn "Existing map Bcb $_ during CcPurgeCacheSection()" if $_; } for ($CObject->{"map"});
+ do { warn "Existing pin Bcb $_ during CcPurgeCacheSection()" if $_; } for (values(%{$CObject->{"pin"}}));
+ # Primary goal of this function:
+ delete $CObject->{"in_memory"};
+ # Really needed:
+ delete $CObject->{"Buffer"};
+}
+
+sub CcFlushCache($$$$)
+{
+my($SectionObjectPointer,$SharedCacheMap,$FileOffset,$Length)=@_;
+
+ $Object->{"CcFlushCached"}=0;
+ $Object->{"FileOffset"}=$FileOffset;
+ $Object->{"Length"}=$Length;
+}
+
+sub CcFlushCache_leave($$)
+{
+my($Status,$Information)=@_;
+
+ warn "CcFlushCache() not the toplevel function"
+ ." (".join(",",map({ $_->{"line_enter"}.":".$_->{"by"}; } @$EnterLeave)).")"
+ if !(0==@$EnterLeave
+ || (1==@$EnterLeave && ${$EnterLeave}[0]->{"by"}=~/^IRP_MJ_/));
+ if ($Status ne "0x".("F"x8) || $Information ne "0x".("F"x8)) {
+ warn "Unexpected Status $Status" if eval $Status;
+ warn "Unexpected Information $Information while CcFlushCached=".$Object->{"CcFlushCached"}
+ if eval($Information)!=eval($Object->{"CcFlushCached"})*0x1000;
+ }
+}
+