ReactOS 0.4.15-dev-7788-g1ad9096
cachesup.c File Reference
#include "cdprocs.h"
Include dependency graph for cachesup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_CACHESUP)
 

Functions

VOID CdCreateInternalStream (_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Inout_ PFCB Fcb, _In_ PUNICODE_STRING Name)
 
VOID CdDeleteInternalStream (_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb)
 
NTSTATUS CdCompleteMdl (_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
 
 _Requires_lock_held_ (_Global_critical_region_)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_CACHESUP)

Definition at line 23 of file cachesup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 463 of file cachesup.c.

496{
498
499 PVOID RestartKey = NULL;
500 PFCB ThisFcb = NULL;
501 PFCB NextFcb;
502
503 BOOLEAN RemovedFcb;
504
505 PAGED_CODE();
506
508
509 //
510 // Force any remaining Fcb's in the delayed close queue to be closed.
511 //
512
513 CdFspClose( Vcb );
514
515 //
516 // Acquire the global file resource.
517 //
518
519 CdAcquireAllFiles( IrpContext, Vcb );
520
521 //
522 // Loop through each Fcb in the Fcb Table and perform the flush.
523 //
524
525 while (TRUE) {
526
527 //
528 // Lock the Vcb to lookup the next Fcb.
529 //
530
531 CdLockVcb( IrpContext, Vcb );
532 NextFcb = CdGetNextFcb( IrpContext, Vcb, &RestartKey );
533
534 //
535 // Reference the NextFcb if present.
536 //
537
538 if (NextFcb != NULL) {
539
540 NextFcb->FcbReference += 1;
541 }
542
543 //
544 // If the last Fcb is present then decrement reference count and call teardown
545 // to see if it should be removed.
546 //
547
548 if (ThisFcb != NULL) {
549
550 ThisFcb->FcbReference -= 1;
551
552 CdUnlockVcb( IrpContext, Vcb );
553
554 CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
555
556 } else {
557
558 CdUnlockVcb( IrpContext, Vcb );
559 }
560
561 //
562 // Break out of the loop if no more Fcb's.
563 //
564
565 if (NextFcb == NULL) {
566
567 break;
568 }
569
570 //
571 // Move to the next Fcb.
572 //
573
574 ThisFcb = NextFcb;
575
576 //
577 // If there is a image section then see if that can be closed.
578 //
579
581
582 MmFlushImageSection( &ThisFcb->FcbNonpaged->SegmentObject, MmFlushForWrite );
583 }
584
585 //
586 // If there is a data section then purge this. If there is an image
587 // section then we won't be able to. Remember this if it is our first
588 // error.
589 //
590
591 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
593 NULL,
594 0,
595 FALSE ) &&
596 (Status == STATUS_SUCCESS)) {
597
599 }
600
601 //
602 // Dereference the internal stream if dismounting.
603 //
604
605 if (DismountUnderway &&
606 (SafeNodeType( ThisFcb ) != CDFS_NTC_FCB_DATA) &&
607 (ThisFcb->FileObject != NULL)) {
608
609 CdDeleteInternalStream( IrpContext, ThisFcb );
610 }
611 }
612
613 //
614 // Now look at the path table and volume Dasd Fcb's.
615 //
616
617 if (DismountUnderway) {
618
619 if (Vcb->PathTableFcb != NULL) {
620
621 ThisFcb = Vcb->PathTableFcb;
622 InterlockedIncrement( (LONG*)&Vcb->PathTableFcb->FcbReference );
623
624 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
626 NULL,
627 0,
628 FALSE ) &&
629 (Status == STATUS_SUCCESS)) {
630
632 }
633
634 CdDeleteInternalStream( IrpContext, ThisFcb );
635
637
638 CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
639 }
640
641 if (Vcb->VolumeDasdFcb != NULL) {
642
643 ThisFcb = Vcb->VolumeDasdFcb;
645
646 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
648 NULL,
649 0,
650 FALSE ) &&
651 (Status == STATUS_SUCCESS)) {
652
654 }
655
657
658 CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
659 }
660 }
661
662 //
663 // Release all of the files.
664 //
665
666 CdReleaseAllFiles( IrpContext, Vcb );
667
668 return Status;
669}
#define PAGED_CODE()
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define ASSERT_EXCLUSIVE_VCB(V)
Definition: cddata.h:258
VOID CdDeleteInternalStream(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb)
Definition: cachesup.c:333
VOID CdFspClose(_In_opt_ PVCB Vcb)
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1023
_In_ PVCB _In_ BOOLEAN DismountUnderway
Definition: cdprocs.h:237
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1028
#define CdReleaseAllFiles(IC, V)
Definition: cdprocs.h:991
PFCB CdGetNextFcb(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _In_ PVOID *RestartKey)
Definition: strucsup.c:2155
#define CdAcquireAllFiles(IC, V)
Definition: cdprocs.h:988
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
#define CDFS_NTC_FCB_DATA
Definition: nodetype.h:31
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
Status
Definition: gdiplustypes.h:25
#define STATUS_UNABLE_TO_DELETE_SECTION
Definition: ntstatus.h:264
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define STATUS_SUCCESS
Definition: shellext.h:65
SECTION_OBJECT_POINTERS SegmentObject
Definition: cdstruc.h:873
Definition: cdstruc.h:902
__volatile LONG FcbReference
Definition: cdstruc.h:964
PFILE_OBJECT FileObject
Definition: ntfs.h:520
PFCB_NONPAGED FcbNonpaged
Definition: cdstruc.h:1003

◆ CdCompleteMdl()

NTSTATUS CdCompleteMdl ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PIRP  Irp 
)

Definition at line 411 of file cachesup.c.

433{
435
436 PAGED_CODE();
437
438 //
439 // Do completion processing.
440 //
441
443
444 CcMdlReadComplete( FileObject, Irp->MdlAddress );
445
446 //
447 // Mdl is now deallocated.
448 //
449
450 Irp->MdlAddress = NULL;
451
452 //
453 // Complete the request and exit right away.
454 //
455
456 CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
457
458 return STATUS_SUCCESS;
459}
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
_In_ PIRP Irp
Definition: csq.h:116
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by _IRQL_requires_max_().

◆ CdCreateInternalStream()

VOID CdCreateInternalStream ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PVCB  Vcb,
_Inout_ PFCB  Fcb,
_In_ PUNICODE_STRING  Name 
)

Definition at line 38 of file cachesup.c.

66{
67 PFILE_OBJECT StreamFile = NULL;
68 BOOLEAN DecrementReference = FALSE;
69
70 BOOLEAN CleanupDirContext = FALSE;
71 BOOLEAN UpdateFcbSizes = FALSE;
72
73 DIRENT Dirent = {0};
75
76 PAGED_CODE();
77
78 ASSERT_IRP_CONTEXT( IrpContext );
79 ASSERT_FCB( Fcb );
80
81 //
82 // We may only have the Fcb shared. Lock the Fcb and do a
83 // safe test to see if we need to really create the file object.
84 //
85
86 CdLockFcb( IrpContext, Fcb );
87
88 if (Fcb->FileObject != NULL) {
89
90 CdUnlockFcb( IrpContext, Fcb );
91 return;
92 }
93
94 //
95 // Use a try-finally to facilitate cleanup.
96 //
97
98 _SEH2_TRY {
99
100 //
101 // Create the internal stream. The Vpb should be pointing at our volume
102 // device object at this point.
103 //
104
105 StreamFile = IoCreateStreamFileObjectLite( NULL, Vcb->Vpb->RealDevice );
106
107 if (StreamFile == NULL) {
108
110 }
111
112 //
113 // Initialize the fields of the file object.
114 //
115
116 StreamFile->ReadAccess = TRUE;
117 StreamFile->WriteAccess = FALSE;
118 StreamFile->DeleteAccess = FALSE;
119
120 StreamFile->SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject;
121
122 //
123 // Set the file object type and increment the Vcb counts.
124 //
125
126 CdSetFileObject( IrpContext,
127 StreamFile,
129 Fcb,
130 NULL );
131
132 //
133 // We'll give stream file objects a name to aid IO profiling etc. We
134 // NULL this in CdDeleteInternalStream before OB deletes the file object,
135 // and before CdRemovePrefix is called (which frees Fcb names).
136 //
137
138 StreamFile->FileName = *Name;
139
140 //
141 // We will reference the current Fcb twice to keep it from going
142 // away in the error path. Otherwise if we dereference it
143 // below in the finally clause a close could cause the Fcb to
144 // be deallocated.
145 //
146
147 CdLockVcb( IrpContext, Vcb );
148 CdIncrementReferenceCounts( IrpContext, Fcb, 2, 0 );
149 CdUnlockVcb( IrpContext, Vcb );
150 DecrementReference = TRUE;
151
152 //
153 // Initialize the cache map for the file.
154 //
155
156 CcInitializeCacheMap( StreamFile,
157 (PCC_FILE_SIZES)&Fcb->AllocationSize,
158 TRUE,
160 Fcb );
161
162 //
163 // Go ahead and store the stream file into the Fcb.
164 //
165
166 Fcb->FileObject = StreamFile;
167 StreamFile = NULL;
168
169 //
170 // If this is the first file object for a directory then we need to
171 // read the self entry for this directory and update the sizes
172 // in the Fcb. We know that the Fcb has been initialized so
173 // that we have a least one sector available to read.
174 //
175
177
178 ULONG NewDataLength;
179
180 //
181 // Initialize the search structures.
182 //
183
184 CdInitializeDirContext( IrpContext, &DirContext );
185 CdInitializeDirent( IrpContext, &Dirent );
186 CleanupDirContext = TRUE;
187
188 //
189 // Read the dirent from disk and transfer the data to the
190 // in-memory dirent.
191 //
192
193 CdLookupDirent( IrpContext,
194 Fcb,
195 Fcb->StreamOffset,
196 &DirContext );
197
198 CdUpdateDirentFromRawDirent( IrpContext, Fcb, &DirContext, &Dirent );
199
200 //
201 // Verify that this really for the self entry. We do this by
202 // updating the name in the dirent and then checking that it matches
203 // one of the hard coded names.
204 //
205
206 CdUpdateDirentName( IrpContext, &Dirent, FALSE );
207
208 if (Dirent.CdFileName.FileName.Buffer != CdUnicodeSelfArray) {
209
211 }
212
213 //
214 // If the data sizes are different then update the header
215 // and Mcb for this Fcb.
216 //
217
218 NewDataLength = BlockAlign( Vcb, Dirent.DataLength + Fcb->StreamOffset );
219
220 if (NewDataLength == 0) {
221
223 }
224
225 if (NewDataLength != Fcb->FileSize.QuadPart) {
226
227 Fcb->AllocationSize.QuadPart =
228 Fcb->FileSize.QuadPart =
229 Fcb->ValidDataLength.QuadPart = NewDataLength;
230
231 CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize );
232
233 CdTruncateAllocation( IrpContext, Fcb, 0 );
234 CdAddInitialAllocation( IrpContext,
235 Fcb,
236 Dirent.StartingOffset,
237 NewDataLength );
238
239 UpdateFcbSizes = TRUE;
240 }
241
242 //
243 // Check for the existence flag and transform to hidden.
244 //
245
246 if (FlagOn( Dirent.DirentFlags, CD_ATTRIBUTE_HIDDEN )) {
247
249 }
250
251 //
252 // Convert the time to NT time.
253 //
254
255 CdConvertCdTimeToNtTime( IrpContext,
256 Dirent.CdTime,
258
259 //
260 // Update the Fcb flags to indicate we have read the
261 // self entry.
262 //
263
265
266 //
267 // If we updated the sizes then we want to purge the file. Go
268 // ahead and unpin and then purge the first page.
269 //
270
271 CdCleanupDirContext( IrpContext, &DirContext );
272 CdCleanupDirent( IrpContext, &Dirent );
273 CleanupDirContext = FALSE;
274
275 if (UpdateFcbSizes) {
276
278 NULL,
279 0,
280 FALSE );
281 }
282 }
283
284 } _SEH2_FINALLY {
285
286 //
287 // Cleanup any dirent structures we may have used.
288 //
289
290 if (CleanupDirContext) {
291
292 CdCleanupDirContext( IrpContext, &DirContext );
293 CdCleanupDirent( IrpContext, &Dirent );
294 }
295
296 //
297 // If we raised then we need to dereference the file object.
298 //
299
300 if (StreamFile != NULL) {
301
302 //
303 // Null the name pointer, since the stream file object never actually
304 // 'owns' the names, we just point it to existing ones.
305 //
306
307 StreamFile->FileName.Buffer = NULL;
308 StreamFile->FileName.MaximumLength = StreamFile->FileName.Length = 0;
309
310 ObDereferenceObject( StreamFile );
312 }
313
314 //
315 // Dereference and unlock the Fcb.
316 //
317
318 if (DecrementReference) {
319
320 CdLockVcb( IrpContext, Vcb );
321 CdDecrementReferenceCounts( IrpContext, Fcb, 1, 0 );
322 CdUnlockVcb( IrpContext, Vcb );
323 }
324
325 CdUnlockFcb( IrpContext, Fcb );
326 } _SEH2_END;
327
328 return;
329}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define CD_ATTRIBUTE_HIDDEN
Definition: cd.h:353
#define CdConvertCdTimeToNtTime(IC, CD, NT)
Definition: cd.h:394
WCHAR CdUnicodeSelfArray[]
Definition: cddata.c:49
CD_DATA CdData
Definition: cddata.c:42
#define ASSERT_IRP_CONTEXT(IC)
Definition: cddata.h:248
#define ASSERT_FCB(F)
Definition: cddata.h:243
VOID CdTruncateAllocation(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ LONGLONG StartingFileOffset)
Definition: allocsup.c:575
VOID CdAddInitialAllocation(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ ULONG StartingBlock, _In_ LONGLONG DataLength)
Definition: allocsup.c:484
#define CdInitializeDirent(IC, D)
Definition: cdprocs.h:536
#define CdLockFcb(IC, F)
Definition: cdprocs.h:1044
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define BlockAlign(V, L)
Definition: cdprocs.h:1638
@ StreamFileOpen
Definition: cdprocs.h:574
VOID CdUpdateDirentName(_In_ PIRP_CONTEXT IrpContext, _Inout_ PDIRENT Dirent, _In_ ULONG IgnoreCase)
Definition: dirsup.c:534
#define CdCleanupDirContext(IC, DC)
Definition: cdprocs.h:548
_In_ PFCB Fcb
Definition: cdprocs.h:159
VOID CdLookupDirent(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ ULONG DirentOffset, _Out_ PDIRENT_ENUM_CONTEXT DirContext)
Definition: dirsup.c:125
#define CdCleanupDirent(IC, D)
Definition: cdprocs.h:542
#define CdInitializeDirContext(IC, DC)
Definition: cdprocs.h:539
#define CdDecrementReferenceCounts(IC, F, C, UC)
Definition: cdprocs.h:1325
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:425
#define CdUnlockFcb(IC, F)
Definition: cdprocs.h:1060
#define CdIncrementReferenceCounts(IC, F, C, UC)
Definition: cdprocs.h:1317
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1859
#define FCB_STATE_INITIALIZED
Definition: cdstruc.h:1042
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
PFILE_OBJECT NTAPI IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:3199
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: cdstruc.h:409
LONGLONG CreationTime
Definition: cdstruc.h:1030
ULONG FcbState
Definition: cdstruc.h:971
ULONG FileAttributes
Definition: cdstruc.h:977
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by CdUpdateVcbFromVolDescriptor(), and CdVerifyOrCreateDirStreamFile().

◆ CdDeleteInternalStream()

VOID CdDeleteInternalStream ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PFCB  Fcb 
)

Definition at line 333 of file cachesup.c.

357{
359
360 PAGED_CODE();
361
362 UNREFERENCED_PARAMETER( IrpContext );
363
364 ASSERT_IRP_CONTEXT( IrpContext );
365 ASSERT_FCB( Fcb );
366
367 //
368 // Lock the Fcb.
369 //
370
371 CdLockFcb( IrpContext, Fcb );
372
373 //
374 // Capture the file object.
375 //
376
379
380 //
381 // It is now safe to unlock the Fcb.
382 //
383
384 CdUnlockFcb( IrpContext, Fcb );
385
386 //
387 // Dereference the file object if present.
388 //
389
390 if (FileObject != NULL) {
391
392 if (FileObject->PrivateCacheMap != NULL) {
393
395 }
396
397 //
398 // Null the name pointer, since the stream file object never actually
399 // 'owns' the names, we just point it to existing ones.
400 //
401
402 FileObject->FileName.Buffer = NULL;
403 FileObject->FileName.MaximumLength = FileObject->FileName.Length = 0;
404
406 }
407}
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

Referenced by _Requires_lock_held_().