ReactOS  0.4.15-dev-2091-gc14c9ca
copy.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for copy.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MAX_ZERO_LENGTH   (256 * 1024)
 

Typedefs

typedef enum _CC_CAN_WRITE_RETRY CC_CAN_WRITE_RETRY
 

Enumerations

enum  _CC_CAN_WRITE_RETRY { FirstTry = 0, RetryAllowRemote = 253, RetryForceCheckPerFile = 254, RetryMasterLocked = 255 }
 

Functions

VOID NTAPI MiZeroPhysicalPage (IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI CcInitCacheZeroPage (VOID)
 
VOID CcPostDeferredWrites (VOID)
 
VOID CcPerformReadAhead (IN PFILE_OBJECT FileObject)
 
BOOLEAN NTAPI CcCanIWrite (IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN BOOLEAN Retrying)
 
static int CcpCheckInvalidUserBuffer (PEXCEPTION_POINTERS Except, PVOID Buffer, ULONG Length)
 
BOOLEAN NTAPI CcCopyRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
 
BOOLEAN NTAPI CcCopyWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
 
VOID NTAPI CcDeferWrite (IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
 
VOID NTAPI CcFastCopyRead (IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN ULONG PageCount, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
 
VOID NTAPI CcFastCopyWrite (IN PFILE_OBJECT FileObject, IN ULONG FileOffset, IN ULONG Length, IN PVOID Buffer)
 
BOOLEAN NTAPI CcZeroData (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartOffset, IN PLARGE_INTEGER EndOffset, IN BOOLEAN Wait)
 

Variables

static PFN_NUMBER CcZeroPage = 0
 
ULONG CcRosTraceLevel = CC_API_DEBUG
 
ULONG CcFastMdlReadWait
 
ULONG CcFastMdlReadNotPossible
 
ULONG CcFastReadNotPossible
 
ULONG CcFastReadWait
 
ULONG CcFastReadNoWait
 
ULONG CcFastReadResourceMiss
 
ULONG CcDataPages = 0
 
ULONG CcDataFlushes = 0
 

Macro Definition Documentation

◆ MAX_ZERO_LENGTH

#define MAX_ZERO_LENGTH   (256 * 1024)

Definition at line 21 of file copy.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file copy.c.

Typedef Documentation

◆ CC_CAN_WRITE_RETRY

Enumeration Type Documentation

◆ _CC_CAN_WRITE_RETRY

Enumerator
FirstTry 
RetryAllowRemote 
RetryForceCheckPerFile 
RetryMasterLocked 

Definition at line 23 of file copy.c.

24 {
25  FirstTry = 0,
26  RetryAllowRemote = 253,
28  RetryMasterLocked = 255,
enum _CC_CAN_WRITE_RETRY CC_CAN_WRITE_RETRY
Definition: copy.c:25

Function Documentation

◆ CcCanIWrite()

BOOLEAN NTAPI CcCanIWrite ( IN PFILE_OBJECT  FileObject,
IN ULONG  BytesToWrite,
IN BOOLEAN  Wait,
IN BOOLEAN  Retrying 
)

Definition at line 298 of file copy.c.

303 {
304  KIRQL OldIrql;
305  KEVENT WaitEvent;
306  ULONG Length, Pages;
307  BOOLEAN PerFileDefer;
310  CC_CAN_WRITE_RETRY TryContext;
311  PROS_SHARED_CACHE_MAP SharedCacheMap;
312 
313  CCTRACE(CC_API_DEBUG, "FileObject=%p BytesToWrite=%lu Wait=%d Retrying=%d\n",
314  FileObject, BytesToWrite, Wait, Retrying);
315 
316  /* Write through is always OK */
318  {
319  return TRUE;
320  }
321 
322  TryContext = Retrying;
323  /* Allow remote file if not from posted */
324  if (IoIsFileOriginRemote(FileObject) && TryContext < RetryAllowRemote)
325  {
326  return TRUE;
327  }
328 
329  /* Don't exceed max tolerated size */
331  if (BytesToWrite < MAX_ZERO_LENGTH)
332  {
333  Length = BytesToWrite;
334  }
335 
336  Pages = BYTES_TO_PAGES(Length);
337 
338  /* By default, assume limits per file won't be hit */
339  PerFileDefer = FALSE;
340  Fcb = FileObject->FsContext;
341  /* Do we have to check for limits per file? */
342  if (TryContext >= RetryForceCheckPerFile ||
344  {
345  /* If master is not locked, lock it now */
346  if (TryContext != RetryMasterLocked)
347  {
349  }
350 
351  /* Let's not assume the file is cached... */
352  if (FileObject->SectionObjectPointer != NULL &&
353  FileObject->SectionObjectPointer->SharedCacheMap != NULL)
354  {
355  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
356  /* Do we have limits per file set? */
357  if (SharedCacheMap->DirtyPageThreshold != 0 &&
358  SharedCacheMap->DirtyPages != 0)
359  {
360  /* Yes, check whether they are blocking */
361  if (Pages + SharedCacheMap->DirtyPages > SharedCacheMap->DirtyPageThreshold)
362  {
363  PerFileDefer = TRUE;
364  }
365  }
366  }
367 
368  /* And don't forget to release master */
369  if (TryContext != RetryMasterLocked)
370  {
372  }
373  }
374 
375  /* So, now allow write if:
376  * - Not the first try or we have no throttling yet
377  * AND:
378  * - We don't exceed threshold!
379  * - We don't exceed what Mm can allow us to use
380  * + If we're above top, that's fine
381  * + If we're above bottom with limited modified pages, that's fine
382  * + Otherwise, throttle!
383  */
384  if ((TryContext != FirstTry || IsListEmpty(&CcDeferredWrites)) &&
388  !PerFileDefer)
389  {
390  return TRUE;
391  }
392 
393  /* If we can wait, we'll start the wait loop for waiting till we can
394  * write for real
395  */
396  if (!Wait)
397  {
398  return FALSE;
399  }
400 
401  /* Otherwise, if there are no deferred writes yet, start the lazy writer */
403  {
404  KIRQL OldIrql;
405 
409  }
410 
411  /* Initialize our wait event */
413 
414  /* And prepare a dummy context */
415  Context.NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
416  Context.NodeByteSize = sizeof(DEFERRED_WRITE);
417  Context.FileObject = FileObject;
418  Context.BytesToWrite = BytesToWrite;
420  Context.Event = &WaitEvent;
421 
422  /* And queue it */
423  if (Retrying)
424  {
425  /* To the top, if that's a retry */
427  &Context.DeferredWriteLinks,
429  }
430  else
431  {
432  /* To the bottom, if that's a first time */
434  &Context.DeferredWriteLinks,
436  }
437 
438  DPRINT1("Actively deferring write for: %p\n", FileObject);
439  /* Now, we'll loop until our event is set. When it is set, it means that caller
440  * can immediately write, and has to
441  */
442  do
443  {
446 
447  return TRUE;
448 }
ULONG CcDirtyPageThreshold
Definition: view.c:55
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID CcPostDeferredWrites(VOID)
Definition: copy.c:73
UCHAR KIRQL
Definition: env_spec_w32.h:591
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
BOOLEAN NTAPI IoIsFileOriginRemote(IN PFILE_OBJECT FileObject)
Definition: file.c:3277
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define NODE_TYPE_DEFERRED_WRITE
Definition: cc.h:286
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define CC_API_DEBUG
Definition: cc.h:11
struct _DEFERRED_WRITE DEFERRED_WRITE
enum _CC_CAN_WRITE_RETRY CC_CAN_WRITE_RETRY
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES
Definition: fsrtltypes.h:47
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
ULONG Flags
Definition: ntfs.h:532
ULONG MmThrottleBottom
Definition: mminit.c:397
#define BYTES_TO_PAGES(Size)
ULONG CcTotalDirtyPages
Definition: view.c:56
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: copy.c:25
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
ULONG MmThrottleTop
Definition: mminit.c:396
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:200
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PFN_NUMBER Total
Definition: mm.h:370
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER CcIdleDelay
Definition: lazywrite.c:46
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PFCB Fcb
Definition: cdprocs.h:159
ULONG DirtyPageThreshold
Definition: cc.h:188
ULONG DirtyPages
Definition: cc.h:180
#define FO_WRITE_THROUGH
Definition: iotypes.h:1776
#define MAX_ZERO_LENGTH
Definition: copy.c:21

Referenced by CcPostDeferredWrites().

◆ CcCopyRead()

BOOLEAN NTAPI CcCopyRead ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
OUT PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 475 of file copy.c.

482 {
483  PROS_VACB Vacb;
484  PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
486  LONGLONG CurrentOffset;
487  LONGLONG ReadEnd = FileOffset->QuadPart + Length;
488  ULONG ReadLength = 0;
489 
490  CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d\n",
491  FileObject, FileOffset->QuadPart, Length, Wait);
492 
493  DPRINT("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
494  "Length %lu, Wait %u, Buffer 0x%p, IoStatus 0x%p)\n",
495  FileObject, FileOffset->QuadPart, Length, Wait,
496  Buffer, IoStatus);
497 
498  if (!SharedCacheMap)
499  return FALSE;
500 
501  /* Documented to ASSERT, but KMTests test this case... */
502  // ASSERT((FileOffset->QuadPart + Length) <= SharedCacheMap->FileSize.QuadPart);
503 
504  CurrentOffset = FileOffset->QuadPart;
505  while(CurrentOffset < ReadEnd)
506  {
507  Status = CcRosGetVacb(SharedCacheMap, CurrentOffset, &Vacb);
508  if (!NT_SUCCESS(Status))
509  {
511  return FALSE;
512  }
513 
514  _SEH2_TRY
515  {
516  ULONG VacbOffset = CurrentOffset % VACB_MAPPING_GRANULARITY;
517  ULONG VacbLength = min(Length, VACB_MAPPING_GRANULARITY - VacbOffset);
518  SIZE_T CopyLength = VacbLength;
519 
520  if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
521  return FALSE;
522 
523  _SEH2_TRY
524  {
525  RtlCopyMemory(Buffer, (PUCHAR)Vacb->BaseAddress + VacbOffset, CopyLength);
526  }
528  {
530  }
531  _SEH2_END;
532 
533  ReadLength += VacbLength;
534 
535  Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
536  CurrentOffset += VacbLength;
537  Length -= VacbLength;
538  }
540  {
541  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
542  }
543  _SEH2_END;
544  }
545 
546  IoStatus->Status = STATUS_SUCCESS;
547  IoStatus->Information = ReadLength;
548 
549 #if 0
550  /* If that was a successful sync read operation, let's handle read ahead */
551  if (Length == 0 && Wait)
552  {
553  PPRIVATE_CACHE_MAP PrivateCacheMap = FileObject->PrivateCacheMap;
554 
555  /* If file isn't random access and next read may get us cross VACB boundary,
556  * schedule next read
557  */
558  if (!BooleanFlagOn(FileObject->Flags, FO_RANDOM_ACCESS) &&
559  (CurrentOffset - 1) / VACB_MAPPING_GRANULARITY != (CurrentOffset + ReadLength - 1) / VACB_MAPPING_GRANULARITY)
560  {
562  }
563 
564  /* And update read history in private cache map */
565  PrivateCacheMap->FileOffset1.QuadPart = PrivateCacheMap->FileOffset2.QuadPart;
566  PrivateCacheMap->BeyondLastByte1.QuadPart = PrivateCacheMap->BeyondLastByte2.QuadPart;
567  PrivateCacheMap->FileOffset2.QuadPart = FileOffset->QuadPart;
568  PrivateCacheMap->BeyondLastByte2.QuadPart = FileOffset->QuadPart + ReadLength;
569  }
570 #endif
571 
572  return TRUE;
573 }
Definition: cc.h:206
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PVOID BaseAddress
Definition: cc.h:209
LARGE_INTEGER BeyondLastByte2
Definition: cctypes.h:80
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define FO_RANDOM_ACCESS
Definition: iotypes.h:1793
#define ExRaiseStatus
Definition: ntoskrnl.h:104
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:882
_SEH2_TRY
Definition: create.c:4226
VOID NTAPI CcScheduleReadAhead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: cachesub.c:92
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
LARGE_INTEGER BeyondLastByte1
Definition: cctypes.h:78
ULONG ReadLength
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define CC_API_DEBUG
Definition: cc.h:11
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
static int CcpCheckInvalidUserBuffer(PEXCEPTION_POINTERS Except, PVOID Buffer, ULONG Length)
Definition: copy.c:452
LARGE_INTEGER FileOffset1
Definition: cctypes.h:77
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_SEH2_END
Definition: create.c:4400
BOOLEAN CcRosEnsureVacbResident(_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
Definition: view.c:835
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
_SEH2_FINALLY
Definition: create.c:4371
#define min(a, b)
Definition: monoChain.cc:55
LARGE_INTEGER FileOffset2
Definition: cctypes.h:79
#define VACB_MAPPING_GRANULARITY
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CcFastCopyRead().

◆ CcCopyWrite()

BOOLEAN NTAPI CcCopyWrite ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN PVOID  Buffer 
)

Definition at line 580 of file copy.c.

586 {
587  PROS_VACB Vacb;
588  PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
590  LONGLONG CurrentOffset;
591  LONGLONG WriteEnd;
592 
593  CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%I64d Length=%lu Wait=%d Buffer=%p\n",
594  FileObject, FileOffset->QuadPart, Length, Wait, Buffer);
595 
596  DPRINT("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, "
597  "Length %lu, Wait %u, Buffer 0x%p)\n",
598  FileObject, FileOffset->QuadPart, Length, Wait, Buffer);
599 
600  if (!SharedCacheMap)
601  return FALSE;
602 
603  Status = RtlLongLongAdd(FileOffset->QuadPart, Length, &WriteEnd);
604  if (!NT_SUCCESS(Status))
606 
607  ASSERT(WriteEnd <= SharedCacheMap->SectionSize.QuadPart);
608 
609  CurrentOffset = FileOffset->QuadPart;
610  while(CurrentOffset < WriteEnd)
611  {
612  ULONG VacbOffset = CurrentOffset % VACB_MAPPING_GRANULARITY;
613  ULONG VacbLength = min(WriteEnd - CurrentOffset, VACB_MAPPING_GRANULARITY - VacbOffset);
614 
615  Status = CcRosGetVacb(SharedCacheMap, CurrentOffset, &Vacb);
616  if (!NT_SUCCESS(Status))
617  {
619  return FALSE;
620  }
621 
622  _SEH2_TRY
623  {
624  if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
625  {
626  return FALSE;
627  }
628 
629  _SEH2_TRY
630  {
631  RtlCopyMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + VacbOffset), Buffer, VacbLength);
632  }
634  {
636  }
637  _SEH2_END;
638 
639  Buffer = (PVOID)((ULONG_PTR)Buffer + VacbLength);
640  CurrentOffset += VacbLength;
641 
642  /* Tell Mm */
643  Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
644  if (!NT_SUCCESS(Status))
646  }
648  {
649  /* Do not mark the VACB as dirty if an exception was raised */
650  CcRosReleaseVacb(SharedCacheMap, Vacb, !_SEH2_AbnormalTermination(), FALSE);
651  }
652  _SEH2_END;
653  }
654 
655  /* Flush if needed */
656  if (FileObject->Flags & FO_WRITE_THROUGH)
657  CcFlushCache(FileObject->SectionObjectPointer, FileOffset, Length, NULL);
658 
659  return TRUE;
660 }
Definition: cc.h:206
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define Add2Ptr(PTR, INC)
PVOID BaseAddress
Definition: cc.h:209
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:104
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:882
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
static int CcpCheckInvalidUserBuffer(PEXCEPTION_POINTERS Except, PVOID Buffer, ULONG Length)
Definition: copy.c:452
_SEH2_END
Definition: create.c:4400
NTSTATUS NTAPI MmMakePagesDirty(_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
Definition: section.c:4963
BOOLEAN CcRosEnsureVacbResident(_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
Definition: view.c:835
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
_SEH2_FINALLY
Definition: create.c:4371
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define VACB_MAPPING_GRANULARITY
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define DPRINT
Definition: sndvol32.h:71
#define FO_WRITE_THROUGH
Definition: iotypes.h:1776

Referenced by CcFastCopyWrite().

◆ CcDeferWrite()

VOID NTAPI CcDeferWrite ( IN PFILE_OBJECT  FileObject,
IN PCC_POST_DEFERRED_WRITE  PostRoutine,
IN PVOID  Context1,
IN PVOID  Context2,
IN ULONG  BytesToWrite,
IN BOOLEAN  Retrying 
)

Definition at line 667 of file copy.c.

674 {
675  KIRQL OldIrql;
678 
679  CCTRACE(CC_API_DEBUG, "FileObject=%p PostRoutine=%p Context1=%p Context2=%p BytesToWrite=%lu Retrying=%d\n",
680  FileObject, PostRoutine, Context1, Context2, BytesToWrite, Retrying);
681 
682  /* Try to allocate a context for queueing the write operation */
684  /* If it failed, immediately execute the operation! */
685  if (Context == NULL)
686  {
687  PostRoutine(Context1, Context2);
688  return;
689  }
690 
691  Fcb = FileObject->FsContext;
692 
693  /* Otherwise, initialize the context */
695  Context->NodeTypeCode = NODE_TYPE_DEFERRED_WRITE;
696  Context->NodeByteSize = sizeof(DEFERRED_WRITE);
697  Context->FileObject = FileObject;
698  Context->PostRoutine = PostRoutine;
699  Context->Context1 = Context1;
700  Context->Context2 = Context2;
701  Context->BytesToWrite = BytesToWrite;
703 
704  /* And queue it */
705  if (Retrying)
706  {
707  /* To the top, if that's a retry */
709  &Context->DeferredWriteLinks,
711  }
712  else
713  {
714  /* To the bottom, if that's a first time */
716  &Context->DeferredWriteLinks,
718  }
719 
720  /* Try to execute the posted writes */
722 
723  /* Schedule a lazy writer run to handle deferred writes */
725  if (!LazyWriter.ScanActive)
726  {
728  }
730 }
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
VOID CcPostDeferredWrites(VOID)
Definition: copy.c:73
UCHAR KIRQL
Definition: env_spec_w32.h:591
PLIST_ENTRY NTAPI ExInterlockedInsertHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:114
LAZY_WRITER LazyWriter
Definition: lazywrite.c:37
#define FALSE
Definition: types.h:117
#define NODE_TYPE_DEFERRED_WRITE
Definition: cc.h:286
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define CC_API_DEBUG
Definition: cc.h:11
struct _DEFERRED_WRITE DEFERRED_WRITE
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
BOOLEAN ScanActive
Definition: cc.h:246
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES
Definition: fsrtltypes.h:47
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
ULONG Flags
Definition: ntfs.h:532
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1094
VOID CcScheduleLazyWriteScan(IN BOOLEAN NoDelay)
Definition: lazywrite.c:200
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT Context1
Definition: tdikrnl.h:1094
#define NULL
Definition: types.h:112
struct tagContext Context
Definition: acpixf.h:1034
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PFCB Fcb
Definition: cdprocs.h:159

◆ CcFastCopyRead()

VOID NTAPI CcFastCopyRead ( IN PFILE_OBJECT  FileObject,
IN ULONG  FileOffset,
IN ULONG  Length,
IN ULONG  PageCount,
OUT PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus 
)

Definition at line 737 of file copy.c.

744 {
745  LARGE_INTEGER LargeFileOffset;
747 
748  CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%lu Length=%lu PageCount=%lu Buffer=%p\n",
749  FileObject, FileOffset, Length, PageCount, Buffer);
750 
751  DBG_UNREFERENCED_PARAMETER(PageCount);
752 
753  LargeFileOffset.QuadPart = FileOffset;
755  &LargeFileOffset,
756  Length,
757  TRUE,
758  Buffer,
759  IoStatus);
760  ASSERT(Success == TRUE);
761 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
#define DBG_UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:318
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copy.c:475
unsigned char BOOLEAN
Definition: bufpool.h:45
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:155
LONGLONG QuadPart
Definition: typedefs.h:114

◆ CcFastCopyWrite()

VOID NTAPI CcFastCopyWrite ( IN PFILE_OBJECT  FileObject,
IN ULONG  FileOffset,
IN ULONG  Length,
IN PVOID  Buffer 
)

Definition at line 768 of file copy.c.

773 {
774  LARGE_INTEGER LargeFileOffset;
776 
777  CCTRACE(CC_API_DEBUG, "FileObject=%p FileOffset=%lu Length=%lu Buffer=%p\n",
779 
780  LargeFileOffset.QuadPart = FileOffset;
782  &LargeFileOffset,
783  Length,
784  TRUE,
785  Buffer);
786  ASSERT(Success == TRUE);
787 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
unsigned char BOOLEAN
Definition: bufpool.h:45
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:159
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copy.c:580
LONGLONG QuadPart
Definition: typedefs.h:114

◆ CcInitCacheZeroPage()

VOID NTAPI CcInitCacheZeroPage ( VOID  )

Definition at line 56 of file copy.c.

58 {
60 
62  //MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
64  if (!NT_SUCCESS(Status))
65  {
66  DbgPrint("Can't allocate CcZeroPage.\n");
67  KeBugCheck(CACHE_MANAGER);
68  }
70 }
#define DbgPrint
Definition: loader.c:25
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:275
#define MC_SYSTEM
Definition: mm.h:93
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define MI_SET_USAGE(x)
Definition: mm.h:250
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PFN_NUMBER CcZeroPage
Definition: copy.c:19

Referenced by CcInitView().

◆ CcpCheckInvalidUserBuffer()

static int CcpCheckInvalidUserBuffer ( PEXCEPTION_POINTERS  Except,
PVOID  Buffer,
ULONG  Length 
)
static

Definition at line 452 of file copy.c.

453 {
454  ULONG_PTR ExceptionAddress;
455  ULONG_PTR BeginAddress = (ULONG_PTR)Buffer;
456  ULONG_PTR EndAddress = (ULONG_PTR)Buffer + Length;
457 
460  if (Except->ExceptionRecord->NumberParameters < 2)
462 
463  ExceptionAddress = Except->ExceptionRecord->ExceptionInformation[1];
464  if ((ExceptionAddress >= BeginAddress) && (ExceptionAddress < EndAddress))
466 
468 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
uint32_t ULONG_PTR
Definition: typedefs.h:65
DWORD ExceptionCode
Definition: compat.h:208
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
Definition: bufpool.h:45
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define ULONG_PTR
Definition: config.h:101
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD NumberParameters
Definition: compat.h:212

Referenced by CcCopyRead(), and CcCopyWrite().

◆ CcPerformReadAhead()

VOID CcPerformReadAhead ( IN PFILE_OBJECT  FileObject)

Definition at line 147 of file copy.c.

149 {
151  LONGLONG CurrentOffset;
152  KIRQL OldIrql;
153  PROS_SHARED_CACHE_MAP SharedCacheMap;
154  PROS_VACB Vacb;
155  ULONG PartialLength;
156  ULONG Length;
157  PPRIVATE_CACHE_MAP PrivateCacheMap;
158  BOOLEAN Locked;
159 
160  SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
161 
162  /* Critical:
163  * PrivateCacheMap might disappear in-between if the handle
164  * to the file is closed (private is attached to the handle not to
165  * the file), so we need to lock the master lock while we deal with
166  * it. It won't disappear without attempting to lock such lock.
167  */
169  PrivateCacheMap = FileObject->PrivateCacheMap;
170  /* If the handle was closed since the read ahead was scheduled, just quit */
171  if (PrivateCacheMap == NULL)
172  {
175  return;
176  }
177  /* Otherwise, extract read offset and length and release private map */
178  else
179  {
181  CurrentOffset = PrivateCacheMap->ReadAheadOffset[1].QuadPart;
182  Length = PrivateCacheMap->ReadAheadLength[1];
184  }
186 
187  /* Time to go! */
188  DPRINT("Doing ReadAhead for %p\n", FileObject);
189  /* Lock the file, first */
190  if (!SharedCacheMap->Callbacks->AcquireForReadAhead(SharedCacheMap->LazyWriteContext, FALSE))
191  {
192  Locked = FALSE;
193  goto Clear;
194  }
195 
196  /* Remember it's locked */
197  Locked = TRUE;
198 
199  /* Don't read past the end of the file */
200  if (CurrentOffset >= SharedCacheMap->FileSize.QuadPart)
201  {
202  goto Clear;
203  }
204  if (CurrentOffset + Length > SharedCacheMap->FileSize.QuadPart)
205  {
206  Length = SharedCacheMap->FileSize.QuadPart - CurrentOffset;
207  }
208 
209  /* Next of the algorithm will lock like CcCopyData with the slight
210  * difference that we don't copy data back to an user-backed buffer
211  * We just bring data into Cc
212  */
213  PartialLength = CurrentOffset % VACB_MAPPING_GRANULARITY;
214  if (PartialLength != 0)
215  {
216  PartialLength = min(Length, VACB_MAPPING_GRANULARITY - PartialLength);
217  Status = CcRosRequestVacb(SharedCacheMap,
218  ROUND_DOWN(CurrentOffset, VACB_MAPPING_GRANULARITY),
219  &Vacb);
220  if (!NT_SUCCESS(Status))
221  {
222  DPRINT1("Failed to request VACB: %lx!\n", Status);
223  goto Clear;
224  }
225 
227  CurrentOffset % VACB_MAPPING_GRANULARITY, PartialLength);
228  if (!NT_SUCCESS(Status))
229  {
230  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
231  DPRINT1("Failed to read data: %lx!\n", Status);
232  goto Clear;
233  }
234 
235  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
236 
237  Length -= PartialLength;
238  CurrentOffset += PartialLength;
239  }
240 
241  while (Length > 0)
242  {
243  ASSERT(CurrentOffset % VACB_MAPPING_GRANULARITY == 0);
244  PartialLength = min(VACB_MAPPING_GRANULARITY, Length);
245  Status = CcRosRequestVacb(SharedCacheMap,
246  CurrentOffset,
247  &Vacb);
248  if (!NT_SUCCESS(Status))
249  {
250  DPRINT1("Failed to request VACB: %lx!\n", Status);
251  goto Clear;
252  }
253 
254  Status = CcRosEnsureVacbResident(Vacb, TRUE, FALSE, 0, PartialLength);
255  if (!NT_SUCCESS(Status))
256  {
257  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
258  DPRINT1("Failed to read data: %lx!\n", Status);
259  goto Clear;
260  }
261 
262  CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE);
263 
264  Length -= PartialLength;
265  CurrentOffset += PartialLength;
266  }
267 
268 Clear:
269  /* See previous comment about private cache map */
271  PrivateCacheMap = FileObject->PrivateCacheMap;
272  if (PrivateCacheMap != NULL)
273  {
274  /* Mark read ahead as unactive */
276  InterlockedAnd((volatile long *)&PrivateCacheMap->UlongFlags, ~PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE);
278  }
280 
281  /* If file was locked, release it */
282  if (Locked)
283  {
284  SharedCacheMap->Callbacks->ReleaseFromReadAhead(SharedCacheMap->LazyWriteContext);
285  }
286 
287  /* And drop our extra reference (See: CcScheduleReadAhead) */
289 
290  return;
291 }
#define InterlockedAnd
Definition: interlocked.h:62
Definition: cc.h:206
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define TRUE
Definition: types.h:120
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
LONG NTSTATUS
Definition: precomp.h:26
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:217
NTSTATUS CcRosRequestVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:933
unsigned char BOOLEAN
PCACHE_MANAGER_CALLBACKS Callbacks
Definition: cc.h:185
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
KSPIN_LOCK ReadAheadSpinLock
Definition: cctypes.h:83
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
PACQUIRE_FOR_READ_AHEAD AcquireForReadAhead
Definition: cctypes.h:41
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
PRELEASE_FROM_READ_AHEAD ReleaseFromReadAhead
Definition: cctypes.h:42
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
BOOLEAN CcRosEnsureVacbResident(_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
Definition: view.c:835
LARGE_INTEGER ReadAheadOffset[2]
Definition: cctypes.h:81
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define VACB_MAPPING_GRANULARITY
PVOID LazyWriteContext
Definition: cc.h:186
LARGE_INTEGER FileSize
Definition: cc.h:175
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
void Clear(USHORT Window)
Definition: hardware.c:684
#define DPRINT
Definition: sndvol32.h:71
ULONG UlongFlags
Definition: cctypes.h:73
#define PRIVATE_CACHE_MAP_READ_AHEAD_ACTIVE
Definition: cctypes.h:64
ULONG ReadAheadLength[2]
Definition: cctypes.h:82
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CcWorkerThread().

◆ CcPostDeferredWrites()

VOID CcPostDeferredWrites ( VOID  )

Definition at line 73 of file copy.c.

74 {
75  ULONG WrittenBytes;
76 
77  /* We'll try to write as much as we can */
78  WrittenBytes = 0;
79  while (TRUE)
80  {
81  KIRQL OldIrql;
82  PLIST_ENTRY ListEntry;
83  PDEFERRED_WRITE DeferredWrite;
84 
85  DeferredWrite = NULL;
86 
87  /* Lock our deferred writes list */
89  for (ListEntry = CcDeferredWrites.Flink;
90  ListEntry != &CcDeferredWrites;
91  ListEntry = ListEntry->Flink)
92  {
93  /* Extract an entry */
94  DeferredWrite = CONTAINING_RECORD(ListEntry, DEFERRED_WRITE, DeferredWriteLinks);
95 
96  /* Compute the modified bytes, based on what we already wrote */
97  WrittenBytes += DeferredWrite->BytesToWrite;
98  /* We overflowed, give up */
99  if (WrittenBytes < DeferredWrite->BytesToWrite)
100  {
101  DeferredWrite = NULL;
102  break;
103  }
104 
105  /* Check we can write */
106  if (CcCanIWrite(DeferredWrite->FileObject, WrittenBytes, FALSE, RetryForceCheckPerFile))
107  {
108  /* We can, so remove it from the list and stop looking for entry */
109  RemoveEntryList(&DeferredWrite->DeferredWriteLinks);
110  break;
111  }
112 
113  /* If we don't accept modified pages, stop here */
114  if (!DeferredWrite->LimitModifiedPages)
115  {
116  DeferredWrite = NULL;
117  break;
118  }
119 
120  /* Reset count as nothing was written yet */
121  WrittenBytes -= DeferredWrite->BytesToWrite;
122  DeferredWrite = NULL;
123  }
125 
126  /* Nothing to write found, give up */
127  if (DeferredWrite == NULL)
128  {
129  break;
130  }
131 
132  /* If we have an event, set it and quit */
133  if (DeferredWrite->Event)
134  {
135  KeSetEvent(DeferredWrite->Event, IO_NO_INCREMENT, FALSE);
136  }
137  /* Otherwise, call the write routine and free the context */
138  else
139  {
140  DeferredWrite->PostRoutine(DeferredWrite->Context1, DeferredWrite->Context2);
141  ExFreePoolWithTag(DeferredWrite, 'CcDw');
142  }
143  }
144 }
BOOLEAN LimitModifiedPages
Definition: cctypes.h:178
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN BOOLEAN Retrying)
Definition: copy.c:298
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY DeferredWriteLinks
Definition: cctypes.h:173
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
LIST_ENTRY CcDeferredWrites
Definition: view.c:57
KSPIN_LOCK CcDeferredWriteSpinLock
Definition: view.c:58
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:119
PFILE_OBJECT FileObject
Definition: cctypes.h:171
PVOID Context1
Definition: cctypes.h:176
#define NULL
Definition: types.h:112
PCC_POST_DEFERRED_WRITE PostRoutine
Definition: cctypes.h:175
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
ULONG BytesToWrite
Definition: cctypes.h:172
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PKEVENT Event
Definition: cctypes.h:174
PVOID Context2
Definition: cctypes.h:177

Referenced by CcCanIWrite(), CcDeferWrite(), and CcLazyWriteScan().

◆ CcZeroData()

BOOLEAN NTAPI CcZeroData ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  StartOffset,
IN PLARGE_INTEGER  EndOffset,
IN BOOLEAN  Wait 
)

Definition at line 794 of file copy.c.

799 {
803  PROS_VACB Vacb;
804  PROS_SHARED_CACHE_MAP SharedCacheMap = FileObject->SectionObjectPointer->SharedCacheMap;
805 
806  CCTRACE(CC_API_DEBUG, "FileObject=%p StartOffset=%I64u EndOffset=%I64u Wait=%d\n",
807  FileObject, StartOffset->QuadPart, EndOffset->QuadPart, Wait);
808 
809  DPRINT("CcZeroData(FileObject 0x%p, StartOffset %I64x, EndOffset %I64x, "
810  "Wait %u)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart,
811  Wait);
812 
813  Length = EndOffset->QuadPart - StartOffset->QuadPart;
814  WriteOffset.QuadPart = StartOffset->QuadPart;
815 
816  if (!SharedCacheMap)
817  {
818  /* Make this a non-cached write */
820  KEVENT Event;
821  PMDL Mdl;
822  ULONG i;
823  ULONG CurrentLength;
824  PPFN_NUMBER PfnArray;
825 
826  /* Setup our Mdl */
828  if (!Mdl)
830 
831  PfnArray = MmGetMdlPfnArray(Mdl);
832  for (i = 0; i < BYTES_TO_PAGES(Mdl->ByteCount); i++)
833  PfnArray[i] = CcZeroPage;
834  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
835 
836  /* Perform the write sequencially */
837  while (Length > 0)
838  {
839  CurrentLength = min(Length, MAX_ZERO_LENGTH);
840 
841  Mdl->ByteCount = CurrentLength;
842 
845  if (Status == STATUS_PENDING)
846  {
848  Status = Iosb.Status;
849  }
850  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
851  {
852  MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
853  }
854  if (!NT_SUCCESS(Status))
855  {
856  IoFreeMdl(Mdl);
858  }
859  WriteOffset.QuadPart += CurrentLength;
860  Length -= CurrentLength;
861  }
862 
863  IoFreeMdl(Mdl);
864 
865  return TRUE;
866  }
867 
868  /* See if we should simply truncate the valid data length */
869  if ((StartOffset->QuadPart < SharedCacheMap->ValidDataLength.QuadPart) && (EndOffset->QuadPart >= SharedCacheMap->ValidDataLength.QuadPart))
870  {
871  DPRINT1("Truncating VDL.\n");
872  SharedCacheMap->ValidDataLength = *StartOffset;
873  return TRUE;
874  }
875 
876  ASSERT(EndOffset->QuadPart <= SharedCacheMap->SectionSize.QuadPart);
877 
878  while(WriteOffset.QuadPart < EndOffset->QuadPart)
879  {
880  ULONG VacbOffset = WriteOffset.QuadPart % VACB_MAPPING_GRANULARITY;
881  ULONG VacbLength = min(Length, VACB_MAPPING_GRANULARITY - VacbOffset);
882 
883  Status = CcRosGetVacb(SharedCacheMap, WriteOffset.QuadPart, &Vacb);
884  if (!NT_SUCCESS(Status))
885  {
887  return FALSE;
888  }
889 
890  _SEH2_TRY
891  {
892  if (!CcRosEnsureVacbResident(Vacb, Wait, FALSE, VacbOffset, VacbLength))
893  {
894  return FALSE;
895  }
896 
897  RtlZeroMemory((PVOID)((ULONG_PTR)Vacb->BaseAddress + VacbOffset), VacbLength);
898 
899  WriteOffset.QuadPart += VacbLength;
900  Length -= VacbLength;
901 
902  /* Tell Mm */
903  Status = MmMakePagesDirty(NULL, Add2Ptr(Vacb->BaseAddress, VacbOffset), VacbLength);
904  if (!NT_SUCCESS(Status))
906  }
908  {
909  /* Do not mark the VACB as dirty if an exception was raised */
910  CcRosReleaseVacb(SharedCacheMap, Vacb, !_SEH2_AbnormalTermination(), FALSE);
911  }
912  _SEH2_END;
913  }
914 
915  /* Flush if needed */
916  if (FileObject->Flags & FO_WRITE_THROUGH)
917  CcFlushCache(FileObject->SectionObjectPointer, StartOffset, EndOffset->QuadPart - StartOffset->QuadPart, NULL);
918 
919  return TRUE;
920 }
Definition: cc.h:206
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define Add2Ptr(PTR, INC)
PVOID BaseAddress
Definition: cc.h:209
#define MmGetMdlPfnArray(_Mdl)
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
LARGE_INTEGER SectionSize
Definition: cc.h:177
#define TRUE
Definition: types.h:120
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:167
_Must_inspect_result_ _In_ WDFUSBPIPE _In_ WDFREQUEST _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET WriteOffset
Definition: wdfusb.h:1914
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:104
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
NTSTATUS CcRosGetVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, LONGLONG FileOffset, PROS_VACB *Vacb)
Definition: view.c:882
_SEH2_TRY
Definition: create.c:4226
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:841
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
int64_t LONGLONG
Definition: typedefs.h:68
#define CC_API_DEBUG
Definition: cc.h:11
#define ASSERT(a)
Definition: mode.c:45
return Iosb
Definition: create.c:4402
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define CCTRACE(x, fmt,...)
Definition: cc.h:36
static PFN_NUMBER CcZeroPage
Definition: copy.c:19
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define BYTES_TO_PAGES(Size)
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
_SEH2_END
Definition: create.c:4400
NTSTATUS NTAPI MmMakePagesDirty(_In_ PEPROCESS Process, _In_ PVOID Address, _In_ ULONG Length)
Definition: section.c:4963
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
BOOLEAN CcRosEnsureVacbResident(_In_ PROS_VACB Vacb, _In_ BOOLEAN Wait, _In_ BOOLEAN NoRead, _In_ ULONG Offset, _In_ ULONG Length)
Definition: view.c:835
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_SEH2_FINALLY
Definition: create.c:4371
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1144
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define DPRINT1
Definition: precomp.h:8
#define VACB_MAPPING_GRANULARITY
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
LARGE_INTEGER ValidDataLength
Definition: cc.h:178
NTSTATUS CcRosReleaseVacb(PROS_SHARED_CACHE_MAP SharedCacheMap, PROS_VACB Vacb, BOOLEAN Dirty, BOOLEAN Mapped)
Definition: view.c:453
#define DPRINT
Definition: sndvol32.h:71
LONGLONG QuadPart
Definition: typedefs.h:114
#define FO_WRITE_THROUGH
Definition: iotypes.h:1776
#define MAX_ZERO_LENGTH
Definition: copy.c:21

◆ MiZeroPhysicalPage()

VOID NTAPI MiZeroPhysicalPage ( IN PFN_NUMBER  PageFrameIndex)

Definition at line 122 of file pfnlist.c.

123 {
124  KIRQL OldIrql;
127 
128  /* Map in hyperspace, then wipe it using XMMI or MEMSET */
133 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:28
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:91
#define ASSERT(a)
Definition: mode.c:45
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:91
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by CcInitCacheZeroPage(), MiAllocatePagesForMdl(), MiSessionCreateInternal(), MiSessionInitializeWorkingSetList(), and MmCreateProcessAddressSpace().

Variable Documentation

◆ CcDataFlushes

ULONG CcDataFlushes = 0

Definition at line 44 of file copy.c.

Referenced by IoSynchronousPageWrite(), and QSI_DEF().

◆ CcDataPages

ULONG CcDataPages = 0

Definition at line 43 of file copy.c.

Referenced by IoSynchronousPageWrite(), and QSI_DEF().

◆ CcFastMdlReadNotPossible

ULONG CcFastMdlReadNotPossible

Definition at line 33 of file copy.c.

◆ CcFastMdlReadWait

ULONG CcFastMdlReadWait

Definition at line 32 of file copy.c.

◆ CcFastReadNotPossible

ULONG CcFastReadNotPossible

Definition at line 34 of file copy.c.

◆ CcFastReadNoWait

ULONG CcFastReadNoWait

Definition at line 36 of file copy.c.

◆ CcFastReadResourceMiss

ULONG CcFastReadResourceMiss

Definition at line 37 of file copy.c.

◆ CcFastReadWait

ULONG CcFastReadWait

Definition at line 35 of file copy.c.

◆ CcRosTraceLevel

ULONG CcRosTraceLevel = CC_API_DEBUG

Definition at line 31 of file copy.c.

◆ CcZeroPage

PFN_NUMBER CcZeroPage = 0
static

Definition at line 19 of file copy.c.

Referenced by CcInitCacheZeroPage(), and CcZeroData().