ReactOS  0.4.14-dev-41-g31d7680
cachesup.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1990-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  Cache.c
8 
9 Abstract:
10 
11  This module implements the cache management routines for the Cdfs
12  FSD and FSP, by calling the Common Cache Manager.
13 
14 
15 --*/
16 
17 #include "cdprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (CDFS_BUG_CHECK_CACHESUP)
24 
25 //
26 // Local debug trace level
27 //
28 
29 #ifdef ALLOC_PRAGMA
30 #pragma alloc_text(PAGE, CdCompleteMdl)
31 #pragma alloc_text(PAGE, CdCreateInternalStream)
32 #pragma alloc_text(PAGE, CdDeleteInternalStream)
33 #pragma alloc_text(PAGE, CdPurgeVolume)
34 #endif
35 
36 
37 VOID
39  _In_ PIRP_CONTEXT IrpContext,
40  _In_ PVCB Vcb,
43  )
44 
45 /*++
46 
47 Routine Description:
48 
49  This function creates an internal stream file for interaction
50  with the cache manager. The Fcb here can be for either a
51  directory stream or for a path table stream.
52 
53 Arguments:
54 
55  Vcb - Vcb for this volume.
56 
57  Fcb - Points to the Fcb for this file. It is either an Index or
58  Path Table Fcb.
59 
60 Return Value:
61 
62  None.
63 
64 --*/
65 
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 );
311  Fcb->FileObject = NULL;
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 }
330 
331 
332 VOID
334  _In_ PIRP_CONTEXT IrpContext,
336  )
337 
338 /*++
339 
340 Routine Description:
341 
342  This function creates an internal stream file for interaction
343  with the cache manager. The Fcb here can be for either a
344  directory stream or for a path table stream.
345 
346 Arguments:
347 
348  Fcb - Points to the Fcb for this file. It is either an Index or
349  Path Table Fcb.
350 
351 Return Value:
352 
353  None.
354 
355 --*/
356 
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 
378  Fcb->FileObject = NULL;
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 }
408 
409 
410 NTSTATUS
412  _In_ PIRP_CONTEXT IrpContext,
414  )
415 
416 /*++
417 
418 Routine Description:
419 
420  This routine performs the function of completing Mdl reads.
421  It should be called only from CdFsdRead.
422 
423 Arguments:
424 
425  Irp - Supplies the originating Irp.
426 
427 Return Value:
428 
429  NTSTATUS - Will always be STATUS_SUCCESS.
430 
431 --*/
432 
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 }
460 
461 
462 
463 _Requires_lock_held_(_Global_critical_region_)
464 NTSTATUS
465 CdPurgeVolume (
466  _In_ PIRP_CONTEXT IrpContext,
467  _In_ PVCB Vcb,
469  )
470 
471 /*++
472 
473 Routine Description:
474 
475  This routine is called to purge the volume. The purpose is to make all the stale file
476  objects in the system go away in order to lock the volume.
477 
478  The Vcb is already acquired exclusively. We will lock out all file operations by
479  acquiring the global file resource. Then we will walk through all of the Fcb's and
480  perform the purge.
481 
482 Arguments:
483 
484  Vcb - Vcb for the volume to purge.
485 
486  DismountUnderway - Indicates that we are trying to delete all of the objects.
487  We will purge the Path Table and VolumeDasd and dereference all
488  internal streams.
489 
490 Return Value:
491 
492  NTSTATUS - The first failure of the purge operation.
493 
494 --*/
495 
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 
636  InterlockedDecrement( (LONG*)&ThisFcb->FcbReference );
637 
638  CdTeardownStructures( IrpContext, ThisFcb, &RemovedFcb );
639  }
640 
641  if (Vcb->VolumeDasdFcb != NULL) {
642 
643  ThisFcb = Vcb->VolumeDasdFcb;
644  InterlockedIncrement( (LONG*)&ThisFcb->FcbReference );
645 
646  if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) &&
648  NULL,
649  0,
650  FALSE ) &&
651  (Status == STATUS_SUCCESS)) {
652 
654  }
655 
656  InterlockedDecrement( (LONG*)&ThisFcb->FcbReference );
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 }
670 
671 
_Requires_lock_held_(_Global_critical_region_)
Definition: cachesup.c:463
LONGLONG CreationTime
Definition: cdstruc.h:1036
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define FCB_STATE_INITIALIZED
Definition: cdstruc.h:1048
#define TRUE
Definition: types.h:120
#define CD_ATTRIBUTE_HIDDEN
Definition: cd.h:353
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define CdAcquireAllFiles(IC, V)
Definition: cdprocs.h:993
PFILE_OBJECT FileObject
Definition: ntfs.h:516
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
Definition: cdstruc.h:908
#define SafeNodeType(Ptr)
Definition: nodetype.h:54
CACHE_MANAGER_CALLBACKS CacheManagerCallbacks
Definition: cdstruc.h:415
ULONG FileAttributes
Definition: cdstruc.h:983
LONG NTSTATUS
Definition: precomp.h:26
VOID CdUpdateDirentName(_In_ PIRP_CONTEXT IrpContext, _Inout_ PDIRENT Dirent, _In_ ULONG IgnoreCase)
Definition: dirsup.c:534
#define CdCleanupDirContext(IC, DC)
Definition: cdprocs.h:553
Definition: cdstruc.h:504
_In_ PVCB _In_ BOOLEAN DismountUnderway
Definition: cdprocs.h:227
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PFILE_OBJECT NTAPI IoCreateStreamFileObjectLite(IN PFILE_OBJECT FileObject OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL)
Definition: file.c:3198
#define ASSERT_FCB(F)
Definition: cddata.h:243
#define PAGED_CODE()
Definition: video.h:57
VOID CdFspClose(_In_opt_ PVCB Vcb)
#define CdUnlockFcb(IC, F)
Definition: cdprocs.h:1065
_SEH2_TRY
Definition: create.c:4250
VOID CdDeleteInternalStream(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb)
Definition: cachesup.c:333
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define CdReleaseAllFiles(IC, V)
Definition: cdprocs.h:996
#define ASSERT_IRP_CONTEXT(IC)
Definition: cddata.h:249
long LONG
Definition: pedump.c:60
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define CDFS_NTC_FCB_DATA
Definition: nodetype.h:31
VOID CdCreateInternalStream(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _Inout_ PFCB Fcb, _In_ PUNICODE_STRING Name)
Definition: cachesup.c:38
struct NameRec_ * Name
Definition: cdprocs.h:464
__volatile LONG FcbReference
Definition: cdstruc.h:970
unsigned char BOOLEAN
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
smooth NULL
Definition: ftsmooth.c:416
#define BlockAlign(V, L)
Definition: cdprocs.h:1648
#define CdDecrementReferenceCounts(IC, F, C, UC)
Definition: cdprocs.h:1330
VOID CdTruncateAllocation(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ LONGLONG StartingFileOffset)
Definition: allocsup.c:575
WCHAR CdUnicodeSelfArray[]
Definition: cddata.c:49
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
CD_DATA CdData
Definition: cddata.c:42
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:193
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4798
#define CdInitializeDirContext(IC, DC)
Definition: cdprocs.h:544
#define CdUnlockVcb(IC, V)
Definition: cdprocs.h:1033
#define Vcb
Definition: cdprocs.h:1425
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT DirContext
Definition: cdprocs.h:429
#define CdInitializeDirent(IC, D)
Definition: cdprocs.h:541
#define _Inout_
Definition: no_sal2.h:244
* PFILE_OBJECT
Definition: iotypes.h:1955
NTSTATUS CdCompleteMdl(_In_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: cachesup.c:411
#define CdLockVcb(IC, V)
Definition: cdprocs.h:1028
#define InterlockedDecrement
Definition: armddk.h:52
#define CdConvertCdTimeToNtTime(IC, CD, NT)
Definition: cd.h:394
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
Status
Definition: gdiplustypes.h:24
#define CdLockFcb(IC, F)
Definition: cdprocs.h:1049
#define _In_
Definition: no_sal2.h:204
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_SEH2_END
Definition: create.c:4424
#define InterlockedIncrement
Definition: armddk.h:53
PFCB CdGetNextFcb(_In_ PIRP_CONTEXT IrpContext, _In_ PVCB Vcb, _In_ PVOID *RestartKey)
Definition: strucsup.c:2155
#define CdRaiseStatus(IC, S)
Definition: cdprocs.h:1869
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:284
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:354
_SEH2_FINALLY
Definition: create.c:4395
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
VOID CdAddInitialAllocation(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ ULONG StartingBlock, _In_ LONGLONG DataLength)
Definition: allocsup.c:484
#define ASSERT_EXCLUSIVE_VCB(V)
Definition: cddata.h:259
SECTION_OBJECT_POINTERS SegmentObject
Definition: cdstruc.h:879
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
#define CdIncrementReferenceCounts(IC, F, C, UC)
Definition: cdprocs.h:1322
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
PFCB_NONPAGED FcbNonpaged
Definition: cdstruc.h:1009
ULONG FcbState
Definition: cdstruc.h:977
#define STATUS_UNABLE_TO_DELETE_SECTION
Definition: ntstatus.h:250
#define CdCleanupDirent(IC, D)
Definition: cdprocs.h:547
VOID CdLookupDirent(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ ULONG DirentOffset, _Out_ PDIRENT_ENUM_CONTEXT DirContext)
Definition: dirsup.c:125