ReactOS 0.4.15-dev-7918-g2a2556c
dirctrl.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 1989-2000 Microsoft Corporation
4
5Module Name:
6
7 DirCtrl.c
8
9Abstract:
10
11 This module implements the File Directory Control routines for Fat called
12 by the dispatch driver.
13
14
15--*/
16
17#include "fatprocs.h"
18
19//
20// The Bug check file id for this module
21//
22
23#define BugCheckFileId (FAT_BUG_CHECK_DIRCTRL)
24
25//
26// The local debug trace level
27//
28
29#define Dbg (DEBUG_TRACE_DIRCTRL)
30
32 L'.', DOS_QM, DOS_QM, DOS_QM};
33
34//
35// Local procedure prototypes
36//
37
38_Requires_lock_held_(_Global_critical_region_)
40FatQueryDirectory (
41 IN PIRP_CONTEXT IrpContext,
42 IN PIRP Irp
43 );
44
45VOID
47 PIRP_CONTEXT IrpContext,
50 );
51
52_Requires_lock_held_(_Global_critical_region_)
54FatNotifyChangeDirectory (
55 IN PIRP_CONTEXT IrpContext,
56 IN PIRP Irp
57 );
58
59#ifdef ALLOC_PRAGMA
60#pragma alloc_text(PAGE, FatCommonDirectoryControl)
61#pragma alloc_text(PAGE, FatFsdDirectoryControl)
62#pragma alloc_text(PAGE, FatNotifyChangeDirectory)
63#pragma alloc_text(PAGE, FatQueryDirectory)
64#pragma alloc_text(PAGE, FatGetDirTimes)
65
66#endif
67
68
73FatFsdDirectoryControl (
74 _In_ PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
76 )
77
78/*++
79
80Routine Description:
81
82 This routine implements the FSD part of directory control
83
84Arguments:
85
86 VolumeDeviceObject - Supplies the volume device object where the
87 file exists
88
89 Irp - Supplies the Irp being processed
90
91Return Value:
92
93 NTSTATUS - The FSD status for the IRP
94
95--*/
96
97{
99 PIRP_CONTEXT IrpContext = NULL;
100
102
103 PAGED_CODE();
104
105 DebugTrace(+1, Dbg, "FatFsdDirectoryControl\n", 0);
106
107 //
108 // Call the common directory Control routine, with blocking allowed if
109 // synchronous
110 //
111
113
115
116 _SEH2_TRY {
117
118 IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
119
120 Status = FatCommonDirectoryControl( IrpContext, Irp );
121
123
124 //
125 // We had some trouble trying to perform the requested
126 // operation, so we'll abort the I/O request with
127 // the error status that we get back from the
128 // execption code
129 //
130
131 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
132 } _SEH2_END;
133
134 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
135
137
138 //
139 // And return to our caller
140 //
141
142 DebugTrace(-1, Dbg, "FatFsdDirectoryControl -> %08lx\n", Status);
143
144 UNREFERENCED_PARAMETER( VolumeDeviceObject );
145
146 return Status;
147}
148
149
150_Requires_lock_held_(_Global_critical_region_)
152FatCommonDirectoryControl (
153 IN PIRP_CONTEXT IrpContext,
154 IN PIRP Irp
155 )
156
157/*++
158
159Routine Description:
160
161 This is the common routine for doing directory control operations called
162 by both the fsd and fsp threads
163
164Arguments:
165
166 Irp - Supplies the Irp to process
167
168Return Value:
169
170 NTSTATUS - The return status for the operation
171
172--*/
173
174{
177
178 PAGED_CODE();
179
180 //
181 // Get a pointer to the current Irp stack location
182 //
183
185
186 DebugTrace(+1, Dbg, "FatCommonDirectoryControl\n", 0);
187 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
188 DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction );
189
190 //
191 // We know this is a directory control so we'll case on the
192 // minor function, and call a internal worker routine to complete
193 // the irp.
194 //
195
196 switch ( IrpSp->MinorFunction ) {
197
199
200 Status = FatQueryDirectory( IrpContext, Irp );
201 break;
202
204
205 Status = FatNotifyChangeDirectory( IrpContext, Irp );
206 break;
207
208 default:
209
210 DebugTrace(0, Dbg, "Invalid Directory Control Minor Function %08lx\n", IrpSp->MinorFunction);
211
214 break;
215 }
216
217 DebugTrace(-1, Dbg, "FatCommonDirectoryControl -> %08lx\n", Status);
218
219 return Status;
220}
221
222
223//
224// Local Support Routine
225//
226
227_Requires_lock_held_(_Global_critical_region_)
229FatQueryDirectory (
230 IN PIRP_CONTEXT IrpContext,
231 IN PIRP Irp
232 )
233
234/*++
235
236Routine Description:
237
238 This routine performs the query directory operation. It is responsible
239 for either completing of enqueuing the input Irp.
240
241Arguments:
242
243 Irp - Supplies the Irp to process
244
245Return Value:
246
247 NTSTATUS - The return status for the operation
248
249--*/
250
251{
254
255 PVCB Vcb;
256 PDCB Dcb;
257 PCCB Ccb;
258 PBCB Bcb;
259
260 ULONG i;
262 CLONG UserBufferLength;
263
264 PUNICODE_STRING UniArgFileName;
265 WCHAR LongFileNameBuffer[ FAT_CREATE_INITIAL_NAME_BUF_SIZE];
266 UNICODE_STRING LongFileName;
267 UNICODE_STRING OrigFileName;
269 ULONG FileIndex;
270 ULONG MatchFlags = 0;
273 BOOLEAN IndexSpecified;
274
275 BOOLEAN InitialQuery;
276 VBO CurrentVbo = 0;
277 BOOLEAN UpdateCcb;
279 UCHAR Fat8Dot3Buffer[12];
280 OEM_STRING Fat8Dot3String;
281 ULONG DiskAllocSize;
282
283 ULONG NextEntry;
284 ULONG LastEntry;
285
287 PFILE_FULL_DIR_INFORMATION FullDirInfo;
288 PFILE_BOTH_DIR_INFORMATION BothDirInfo;
289 PFILE_ID_FULL_DIR_INFORMATION IdFullDirInfo;
290 PFILE_ID_BOTH_DIR_INFORMATION IdBothDirInfo;
291 PFILE_NAMES_INFORMATION NamesInfo;
292
293
294 PAGED_CODE();
295
296 //
297 // Get the current Stack location
298 //
299
301
302 //
303 // Display the input values.
304 //
305 DebugTrace(+1, Dbg, "FatQueryDirectory...\n", 0);
306 DebugTrace( 0, Dbg, " Wait = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
307 DebugTrace( 0, Dbg, " Irp = %p\n", Irp);
308 DebugTrace( 0, Dbg, " ->Length = %08lx\n", IrpSp->Parameters.QueryDirectory.Length);
309 DebugTrace( 0, Dbg, " ->FileName = %wZ\n", IrpSp->Parameters.QueryDirectory.FileName);
310 DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
311 DebugTrace( 0, Dbg, " ->FileIndex = %08lx\n", IrpSp->Parameters.QueryDirectory.FileIndex);
312 DebugTrace( 0, Dbg, " ->UserBuffer = %p\n", Irp->AssociatedIrp.SystemBuffer);
313 DebugTrace( 0, Dbg, " ->RestartScan = %08lx\n", FlagOn( IrpSp->Flags, SL_RESTART_SCAN ));
314 DebugTrace( 0, Dbg, " ->ReturnSingleEntry = %08lx\n", FlagOn( IrpSp->Flags, SL_RETURN_SINGLE_ENTRY ));
315 DebugTrace( 0, Dbg, " ->IndexSpecified = %08lx\n", FlagOn( IrpSp->Flags, SL_INDEX_SPECIFIED ));
316
317 //
318 // Reference our input parameters to make things easier
319 //
320
321 UserBufferLength = IrpSp->Parameters.QueryDirectory.Length;
322
323 FileInformationClass = IrpSp->Parameters.QueryDirectory.FileInformationClass;
324 FileIndex = IrpSp->Parameters.QueryDirectory.FileIndex;
325
326 UniArgFileName = IrpSp->Parameters.QueryDirectory.FileName;
327
330 IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);
331
332 //
333 // Check on the type of open. We return invalid parameter for all
334 // but UserDirectoryOpens. Also check that the filename is a valid
335 // UNICODE string.
336 //
337
339 &Vcb,
340 &Dcb,
341 &Ccb) != UserDirectoryOpen ||
342 (UniArgFileName &&
343 UniArgFileName->Length % sizeof(WCHAR))) {
344
346 DebugTrace(-1, Dbg, "FatQueryDirectory -> STATUS_INVALID_PARAMETER\n", 0);
347
349 }
350
351 //
352 // Initialize the local variables.
353 //
354
355 Bcb = NULL;
356 UpdateCcb = TRUE;
357 Dirent = NULL;
358
359 Fat8Dot3String.MaximumLength = 12;
360 Fat8Dot3String.Buffer = (PCHAR)Fat8Dot3Buffer;
361
362 LongFileName.Length = 0;
363 LongFileName.MaximumLength = sizeof( LongFileNameBuffer);
364 LongFileName.Buffer = LongFileNameBuffer;
365
366 InitialQuery = (BOOLEAN)((Ccb->UnicodeQueryTemplate.Buffer == NULL) &&
369 Irp->IoStatus.Information = 0;
370
371 DiskAllocSize = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;
372
373 //
374 // If this is the initial query, then grab exclusive access in
375 // order to update the search string in the Ccb. We may
376 // discover that we are not the initial query once we grab the Fcb
377 // and downgrade our status.
378 //
379 // If restartscan is set, we may be replacing the query template,
380 // so take the FCB exclusive to protect against multiple people
381 // changing the CCB at once.
382 //
383
384 if (InitialQuery || RestartScan) {
385
386 if (!FatAcquireExclusiveFcb( IrpContext, Dcb )) {
387
388 DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0);
389 Status = FatFsdPostRequest( IrpContext, Irp );
390 DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);
391
392 return Status;
393 }
394
395 if (!RestartScan && (Ccb->UnicodeQueryTemplate.Buffer != NULL)) {
396
397 InitialQuery = FALSE;
398
399 FatConvertToSharedFcb( IrpContext, Dcb );
400 }
401
402 } else {
403
404 if (!FatAcquireSharedFcb( IrpContext, Dcb )) {
405
406 DebugTrace(0, Dbg, "FatQueryDirectory -> Enqueue to Fsp\n", 0);
407 Status = FatFsdPostRequest( IrpContext, Irp );
408 DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);
409
410 return Status;
411
412 }
413 }
414
415 _SEH2_TRY {
416
417 ULONG BaseLength;
418 ULONG BytesConverted;
419
420 //
421 // If we are in the Fsp now because we had to wait earlier,
422 // we must map the user buffer, otherwise we can use the
423 // user's buffer directly.
424 //
425
426 Buffer = FatMapUserBuffer( IrpContext, Irp );
427
428 //
429 // Make sure the Dcb is still good.
430 //
431
432 FatVerifyFcb( IrpContext, Dcb );
433
434 //
435 // Determine where to start the scan. Highest priority is given
436 // to the file index. Lower priority is the restart flag. If
437 // neither of these is specified, then the Vbo offset field in the
438 // Ccb is used.
439 //
440
441 if (IndexSpecified) {
442
443 CurrentVbo = FileIndex + sizeof( DIRENT );
444
445 } else if (RestartScan) {
446
447 CurrentVbo = 0;
448 Ccb->OffsetToStartSearchFrom = 0;
449
450 } else {
451
452 CurrentVbo = Ccb->OffsetToStartSearchFrom;
453 }
454
455 //
456 // If this is the first try then allocate a buffer for the file
457 // name.
458 //
459
460 if (InitialQuery ||
461 (RestartScan && UniArgFileName != NULL && UniArgFileName->Length != 0)) {
462
463 //
464 // If we're restarting the scan, clear out the pattern in the Ccb and regenerate it,
465 //
466
467 if (RestartScan) {
468
469 if (Ccb->UnicodeQueryTemplate.Buffer) {
470
472
473 ExFreePoolWithTag(Ccb->UnicodeQueryTemplate.Buffer, TAG_FILENAME_BUFFER);
475 }
476
477 Ccb->UnicodeQueryTemplate.Buffer = NULL;
478 Ccb->UnicodeQueryTemplate.Length = 0;
479 Ccb->UnicodeQueryTemplate.MaximumLength = 0;
480 }
481
482 if (Ccb->OemQueryTemplate.Wild.Buffer) {
483
485
486 RtlFreeOemString( &Ccb->OemQueryTemplate.Wild );
488 }
489
490 Ccb->OemQueryTemplate.Wild.Buffer = NULL;
491 Ccb->OemQueryTemplate.Wild.Length = 0;
492 Ccb->OemQueryTemplate.Wild.MaximumLength = 0;
493 }
494
495 Ccb->ContainsWildCards = FALSE;
500
501 }
502
503 //
504 // If either:
505 //
506 // - No name was specified
507 // - An empty name was specified
508 // - We received a '*'
509 // - The user specified the DOS equivolent of ????????.???
510 //
511 // then match all names.
512 //
513
514 if ((UniArgFileName == NULL) ||
515 (UniArgFileName->Length == 0) ||
516 (UniArgFileName->Buffer == NULL) ||
517 ((UniArgFileName->Length == sizeof(WCHAR)) &&
518 (UniArgFileName->Buffer[0] == L'*')) ||
519 ((UniArgFileName->Length == 12*sizeof(WCHAR)) &&
520 (RtlEqualMemory( UniArgFileName->Buffer,
522 12*sizeof(WCHAR) )))) {
523
524 Ccb->ContainsWildCards = TRUE;
525
527
528 } else {
529
530 BOOLEAN ExtendedName = FALSE;
531 OEM_STRING LocalBestFit;
532
533 //
534 // First and formost, see if the name has wild cards.
535 //
536
537 Ccb->ContainsWildCards =
538 FsRtlDoesNameContainWildCards( UniArgFileName );
539
540 //
541 // Now check to see if the name contains any extended
542 // characters
543 //
544
545 for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) {
546
547 if (UniArgFileName->Buffer[i] >= 0x80) {
548
549 ExtendedName = TRUE;
550 break;
551 }
552 }
553
554 //
555 // OK, now do the conversions we need.
556 //
557
558 if (ExtendedName) {
559
560 Status = RtlUpcaseUnicodeString( &Ccb->UnicodeQueryTemplate,
561 UniArgFileName,
562 TRUE );
563
564 if (!NT_SUCCESS(Status)) {
565
567 }
568
570
571 //
572 // Upcase the name and convert it to the Oem code page.
573 //
574
576 UniArgFileName,
577 TRUE );
578
579 //
580 // If this conversion failed for any reason other than
581 // an unmappable character fail the request.
582 //
583
584 if (!NT_SUCCESS(Status)) {
585
587
589
590 } else {
591
593 }
594
595 } else {
596
598 }
599
600 } else {
601
603
604 //
605 // This case is optimized because I know I only have to
606 // worry about a-z.
607 //
608
610 UniArgFileName->Length +
611 UniArgFileName->Length / sizeof(WCHAR),
613
614 Ccb->UnicodeQueryTemplate.Buffer = Buffers;
615 Ccb->UnicodeQueryTemplate.Length = UniArgFileName->Length;
616 Ccb->UnicodeQueryTemplate.MaximumLength = UniArgFileName->Length;
617
618 LocalBestFit.Buffer = (PCHAR)Buffers + UniArgFileName->Length;
619 LocalBestFit.Length = UniArgFileName->Length / sizeof(WCHAR);
620 LocalBestFit.MaximumLength = LocalBestFit.Length;
621
623
624 for (i=0; i < UniArgFileName->Length / sizeof(WCHAR); i++) {
625
626 WCHAR c = UniArgFileName->Buffer[i];
627
628 LocalBestFit.Buffer[i] = (UCHAR)
629 (Ccb->UnicodeQueryTemplate.Buffer[i] =
630 (c < 'a' ? c : c <= 'z' ? c - ('a' - 'A') : c));
631 }
632 }
633
634 //
635 // At this point we now have the upcased unicode name,
636 // and the two Oem names if they could be represented in
637 // this code page.
638 //
639 // Now determine if the Oem names are legal for what we
640 // going to try and do. Mark them as not usable is they
641 // are not legal. Note that we can optimize extended names
642 // since they are actually both the same string.
643 //
644
646 !FatIsNameShortOemValid( IrpContext,
647 LocalBestFit,
648 Ccb->ContainsWildCards,
649 FALSE,
650 FALSE )) {
651
652 if (ExtendedName) {
653
654 RtlFreeOemString( &LocalBestFit );
656 }
657
659 }
660
661 //
662 // OK, now both locals oem strings correctly reflect their
663 // usability. Now we want to load up the Ccb structure.
664 //
665 // Now we will branch on two paths of wheather the name
666 // is wild or not.
667 //
668
670
671 if (Ccb->ContainsWildCards) {
672
673 Ccb->OemQueryTemplate.Wild = LocalBestFit;
674
675 } else {
676
677 FatStringTo8dot3( IrpContext,
678 LocalBestFit,
679 &Ccb->OemQueryTemplate.Constant );
680
682
683 RtlFreeOemString( &LocalBestFit );
685 }
686 }
687 }
688 }
689
690 //
691 // We convert to shared access.
692 //
693
694 FatConvertToSharedFcb( IrpContext, Dcb );
695 }
696
697 LastEntry = 0;
698 NextEntry = 0;
699
700 switch (FileInformationClass) {
701
703
705 FileName[0] );
706 break;
707
709
711 FileName[0] );
712 break;
713
715
717 FileName[0] );
718 break;
719
721
723 FileName[0] );
724 break;
725
727
729 FileName[0] );
730 break;
731
733
735 FileName[0] );
736 break;
737
738 default:
739
741 }
742
743 //
744 // At this point we are about to enter our query loop. We have
745 // determined the index into the directory file to begin the
746 // search. LastEntry and NextEntry are used to index into the user
747 // buffer. LastEntry is the last entry we've added, NextEntry is
748 // current one we're working on. If NextEntry is non-zero, then
749 // at least one entry was added.
750 //
751
752 while ( TRUE ) {
753
754 VBO NextVbo;
756 ULONG BytesRemainingInBuffer;
757 BOOLEAN FileNameDos;
758
759 DebugTrace(0, Dbg, "FatQueryDirectory -> Top of loop\n", 0);
760
761 //
762 // If the user had requested only a single match and we have
763 // returned that, then we stop at this point.
764 //
765
766 if (ReturnSingleEntry && NextEntry != 0) {
767
769 }
770
771
772 //
773 // We call FatLocateDirent to lock down the next matching dirent.
774 //
775
776 FatLocateDirent( IrpContext,
777 Dcb,
778 Ccb,
779 CurrentVbo,
780 &MatchFlags,
781 &Dirent,
782 &Bcb,
783 &NextVbo,
784 &FileNameDos,
785 &LongFileName,
786 &OrigFileName );
787
788 //
789 // If we didn't receive a dirent, then we are at the end of the
790 // directory. If we have returned any files, we exit with
791 // success, otherwise we return STATUS_NO_MORE_FILES.
792 //
793
794 if (!Dirent) {
795
796 DebugTrace(0, Dbg, "FatQueryDirectory -> No dirent\n", 0);
797
798 if (NextEntry == 0) {
799
800 UpdateCcb = FALSE;
801
802 if (InitialQuery) {
803
805
806 } else {
807
809 }
810 }
811
813 }
814
815
816 //
817 // Protect access to the user buffer with an exception handler.
818 // Since (at our request) IO doesn't buffer these requests, we have
819 // to guard against a user messing with the page protection and other
820 // such trickery.
821 //
822
823 _SEH2_TRY {
824
825 Fat8dot3ToString( IrpContext, Dirent, TRUE, &Fat8Dot3String );
826
827
828 if (LongFileName.Length == 0) {
829
830 //
831 // Now we have an entry to return to our caller. We'll convert
832 // the name from the form in the dirent to a <name>.<ext> form.
833 // We'll case on the type of information requested and fill up
834 // the user buffer if everything fits.
835 //
836
837 //
838 // Determine the UNICODE length of the file name.
839 //
840
842
843 //
844 // Here are the rules concerning filling up the buffer:
845 //
846 // 1. The Io system garentees that there will always be
847 // enough room for at least one base record.
848 //
849 // 2. If the full first record (including file name) cannot
850 // fit, as much of the name as possible is copied and
851 // STATUS_BUFFER_OVERFLOW is returned.
852 //
853 // 3. If a subsequent record cannot completely fit into the
854 // buffer, none of it (as in 0 bytes) is copied, and
855 // STATUS_SUCCESS is returned. A subsequent query will
856 // pick up with this record.
857 //
858
859 BytesRemainingInBuffer = UserBufferLength - NextEntry;
860
861 if ( (NextEntry != 0) &&
862 ( (BaseLength + FileNameLength > BytesRemainingInBuffer) ||
863 (UserBufferLength < NextEntry) ) ) {
864
865 DebugTrace(0, Dbg, "Next entry won't fit\n", 0);
866
868 }
869
870 NT_ASSERT( BytesRemainingInBuffer >= BaseLength );
871
872 //
873 // Zero the base part of the structure.
874 //
875
876 RtlZeroMemory( &Buffer[NextEntry], BaseLength );
877
878 switch ( FileInformationClass ) {
879
880 //
881 // Now fill the base parts of the strucure that are applicable.
882 //
883
888
889 DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0);
890
891 //
892 // Get the Ea file length.
893 //
894
895 FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry];
896
897 //
898 // If the EAs are corrupt, ignore the error. We don't want
899 // to abort the directory query.
900 //
901
902 _SEH2_TRY {
903
904 FatGetEaLength( IrpContext,
905 Vcb,
906 Dirent,
907 &FullDirInfo->EaSize );
908
910
911 FatResetExceptionState( IrpContext );
912 FullDirInfo->EaSize = 0;
913 } _SEH2_END;
914
916
917 DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry];
918
919 FatGetDirTimes( IrpContext, Dirent, DirInfo );
920
921 DirInfo->EndOfFile.QuadPart = Dirent->FileSize;
922
923 if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {
924
925
926 DirInfo->AllocationSize.QuadPart =
927 (((Dirent->FileSize + DiskAllocSize - 1) / DiskAllocSize) *
928 DiskAllocSize );
929 }
930
931 if (Dirent->Attributes != 0) {
932 DirInfo->FileAttributes = Dirent->Attributes;
933
934
935 } else {
936
937 DirInfo->FileAttributes = 0;
938
940 }
941
942 DirInfo->FileIndex = NextVbo;
943
945
946 DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String);
947
948 break;
949
951
952 DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0);
953
954 NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry];
955
956 NamesInfo->FileIndex = NextVbo;
957
958 NamesInfo->FileNameLength = FileNameLength;
959
960 DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String );
961
962 break;
963
964 default:
965
966#ifdef _MSC_VER
967#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
968#endif
970 }
971
972 BytesConverted = 0;
973
974 Status = RtlOemToUnicodeN( (PWCH)&Buffer[NextEntry + BaseLength],
975 BytesRemainingInBuffer - BaseLength,
976 &BytesConverted,
977 Fat8Dot3String.Buffer,
978 Fat8Dot3String.Length );
979
980 //
981 // Check for the case that a single entry doesn't fit.
982 // This should only get this far on the first entry
983 //
984
985 if (BytesConverted < FileNameLength) {
986
987 NT_ASSERT( NextEntry == 0 );
989 }
990
991 //
992 // Set up the previous next entry offset
993 //
994
995 *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry;
996
997 //
998 // And indicate how much of the user buffer we have currently
999 // used up. We must compute this value before we long align
1000 // ourselves for the next entry
1001 //
1002
1003 Irp->IoStatus.Information = QuadAlign( Irp->IoStatus.Information ) +
1004 BaseLength + BytesConverted;
1005
1006 //
1007 // If something happened with the conversion, bail here.
1008 //
1009
1010 if ( !NT_SUCCESS( Status ) ) {
1011
1013 }
1014
1015 } else {
1016
1017 ULONG ShortNameLength;
1018
1019 FileNameLength = LongFileName.Length;
1020
1021 //
1022 // Here are the rules concerning filling up the buffer:
1023 //
1024 // 1. The Io system garentees that there will always be
1025 // enough room for at least one base record.
1026 //
1027 // 2. If the full first record (including file name) cannot
1028 // fit, as much of the name as possible is copied and
1029 // STATUS_BUFFER_OVERFLOW is returned.
1030 //
1031 // 3. If a subsequent record cannot completely fit into the
1032 // buffer, none of it (as in 0 bytes) is copied, and
1033 // STATUS_SUCCESS is returned. A subsequent query will
1034 // pick up with this record.
1035 //
1036
1037 BytesRemainingInBuffer = UserBufferLength - NextEntry;
1038
1039 if ( (NextEntry != 0) &&
1040 ( (BaseLength + FileNameLength > BytesRemainingInBuffer) ||
1041 (UserBufferLength < NextEntry) ) ) {
1042
1043 DebugTrace(0, Dbg, "Next entry won't fit\n", 0);
1044
1046 }
1047
1048 NT_ASSERT( BytesRemainingInBuffer >= BaseLength );
1049
1050 //
1051 // Zero the base part of the structure.
1052 //
1053
1054 RtlZeroMemory( &Buffer[NextEntry], BaseLength );
1055
1056 switch ( FileInformationClass ) {
1057
1058 //
1059 // Now fill the base parts of the strucure that are applicable.
1060 //
1061
1064
1065 BothDirInfo = (PFILE_BOTH_DIR_INFORMATION)&Buffer[NextEntry];
1066
1067 //
1068 // Now we have an entry to return to our caller. We'll convert
1069 // the name from the form in the dirent to a <name>.<ext> form.
1070 // We'll case on the type of information requested and fill up
1071 // the user buffer if everything fits.
1072 //
1073
1074 Fat8dot3ToString( IrpContext, Dirent, FALSE, &Fat8Dot3String );
1075
1076 NT_ASSERT( Fat8Dot3String.Length <= 12 );
1077
1078 Status = RtlOemToUnicodeN( &BothDirInfo->ShortName[0],
1079 12*sizeof(WCHAR),
1080 &ShortNameLength,
1081 Fat8Dot3String.Buffer,
1082 Fat8Dot3String.Length );
1083
1085 NT_ASSERT( ShortNameLength <= 12*sizeof(WCHAR) );
1086
1087 //
1088 // Copy the length into the dirinfo structure. Note
1089 // that the LHS below is a USHORT, so it can not
1090 // be specificed as the OUT parameter above.
1091 //
1092
1093 BothDirInfo->ShortNameLength = (UCHAR)ShortNameLength;
1094
1095 //
1096 // If something happened with the conversion, bail here.
1097 //
1098
1099 if ( !NT_SUCCESS( Status ) ) {
1100
1102 }
1103
1106
1107 DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file full directory information\n", 0);
1108
1109 //
1110 // Get the Ea file length.
1111 //
1112
1113 FullDirInfo = (PFILE_FULL_DIR_INFORMATION)&Buffer[NextEntry];
1114
1115 //
1116 // If the EAs are corrupt, ignore the error. We don't want
1117 // to abort the directory query.
1118 //
1119
1120 _SEH2_TRY {
1121
1122 FatGetEaLength( IrpContext,
1123 Vcb,
1124 Dirent,
1125 &FullDirInfo->EaSize );
1126
1128
1129 FatResetExceptionState( IrpContext );
1130 FullDirInfo->EaSize = 0;
1131 } _SEH2_END;
1132
1134
1135 DirInfo = (PFILE_DIRECTORY_INFORMATION)&Buffer[NextEntry];
1136
1137 FatGetDirTimes( IrpContext, Dirent, DirInfo );
1138
1139 DirInfo->EndOfFile.QuadPart = Dirent->FileSize;
1140
1141 if (!FlagOn( Dirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY )) {
1142
1143
1144 DirInfo->AllocationSize.QuadPart = (
1145 (( Dirent->FileSize
1146 + DiskAllocSize - 1 )
1147 / DiskAllocSize )
1148 * DiskAllocSize );
1149 }
1150
1151 if (Dirent->Attributes != 0) {
1152 DirInfo->FileAttributes = Dirent->Attributes;
1153
1154
1155 } else {
1156
1157 DirInfo->FileAttributes = 0;
1158
1159
1161 }
1162
1163
1164 DirInfo->FileIndex = NextVbo;
1165
1166 DirInfo->FileNameLength = FileNameLength;
1167
1168 DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String);
1169
1170 break;
1171
1173
1174 DebugTrace(0, Dbg, "FatQueryDirectory -> Getting file names information\n", 0);
1175
1176 NamesInfo = (PFILE_NAMES_INFORMATION)&Buffer[NextEntry];
1177
1178 NamesInfo->FileIndex = NextVbo;
1179
1180 NamesInfo->FileNameLength = FileNameLength;
1181
1182 DebugTrace(0, Dbg, "FatQueryDirectory -> Name = \"%Z\"\n", &Fat8Dot3String );
1183
1184 break;
1185
1186 default:
1187
1188#ifdef _MSC_VER
1189#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1190#endif
1192 }
1193
1194 BytesConverted = BytesRemainingInBuffer - BaseLength >= FileNameLength ?
1196 BytesRemainingInBuffer - BaseLength;
1197
1198 RtlCopyMemory( &Buffer[NextEntry + BaseLength],
1199 &LongFileName.Buffer[0],
1200 BytesConverted );
1201
1202 //
1203 // Set up the previous next entry offset
1204 //
1205
1206 *((PULONG)(&Buffer[LastEntry])) = NextEntry - LastEntry;
1207
1208 //
1209 // And indicate how much of the user buffer we have currently
1210 // used up. We must compute this value before we long align
1211 // ourselves for the next entry
1212 //
1213
1214 Irp->IoStatus.Information = QuadAlign( Irp->IoStatus.Information ) +
1215 BaseLength + BytesConverted;
1216
1217 //
1218 // Check for the case that a single entry doesn't fit.
1219 // This should only get this far on the first entry.
1220 //
1221
1222 if (BytesConverted < FileNameLength) {
1223
1224 NT_ASSERT( NextEntry == 0 );
1225
1227 }
1228 }
1229
1230 //
1231 // Finish up by filling in the FileId
1232 //
1233
1234 switch ( FileInformationClass ) {
1235
1237
1238 IdBothDirInfo = (PFILE_ID_BOTH_DIR_INFORMATION)&Buffer[NextEntry];
1239 IdBothDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
1240 break;
1241
1243
1244 IdFullDirInfo = (PFILE_ID_FULL_DIR_INFORMATION)&Buffer[NextEntry];
1245 IdFullDirInfo->FileId.QuadPart = FatGenerateFileIdFromDirentAndOffset( Dcb, Dirent, NextVbo );
1246 break;
1247
1248 default:
1249 break;
1250 }
1251
1253
1254 //
1255 // We had a problem filling in the user's buffer, so stop and
1256 // fail this request. This is the only reason any exception
1257 // would have occured at this level.
1258 //
1259
1260 Irp->IoStatus.Information = 0;
1261 UpdateCcb = FALSE;
1263 } _SEH2_END;
1264
1265 //
1266 // Set ourselves up for the next iteration
1267 //
1268
1269 LastEntry = NextEntry;
1270 NextEntry += (ULONG)QuadAlign(BaseLength + BytesConverted);
1271
1272 CurrentVbo = NextVbo + sizeof( DIRENT );
1273 }
1274
1275 try_exit: NOTHING;
1276 } _SEH2_FINALLY {
1277
1278 DebugUnwind( FatQueryDirectory );
1279
1280 FatReleaseFcb( IrpContext, Dcb );
1281
1282 //
1283 // Unpin data in cache if still held.
1284 //
1285
1286 FatUnpinBcb( IrpContext, Bcb );
1287
1288 //
1289 // Free any dynamically allocated string buffer
1290 //
1291
1292 FatFreeStringBuffer( &LongFileName);
1293
1294 //
1295 // Perform any cleanup. If this is the first query, then store
1296 // the filename in the Ccb if successful. Also update the
1297 // VBO index for the next search. This is done by transferring
1298 // from shared access to exclusive access and copying the
1299 // data from the local copies.
1300 //
1301
1303
1304 if (UpdateCcb) {
1305
1306 //
1307 // Store the most recent VBO to use as a starting point for
1308 // the next search.
1309 //
1310
1311 Ccb->OffsetToStartSearchFrom = CurrentVbo;
1312 }
1313
1314 FatCompleteRequest( IrpContext, Irp, Status );
1315 }
1316
1317 DebugTrace(-1, Dbg, "FatQueryDirectory -> %08lx\n", Status);
1318
1319 } _SEH2_END;
1320
1321 return Status;
1322}
1323
1324
1325//
1326// Local Support Routine
1327//
1328
1329VOID
1331 PIRP_CONTEXT IrpContext,
1334 )
1335
1336/*++
1337
1338Routine Description:
1339
1340 This routine pulls the date/time information from a dirent and fills
1341 in the DirInfo structure.
1342
1343Arguments:
1344
1345 Dirent - Supplies the dirent
1346 DirInfo - Supplies the target structure
1347
1348Return Value:
1349
1350 VOID
1351
1352--*/
1353
1354
1355{
1356 PAGED_CODE();
1357
1358 //
1359 // Start with the Last Write Time.
1360 //
1361
1362 DirInfo->LastWriteTime =
1363 FatFatTimeToNtTime( IrpContext,
1365 0 );
1366
1367 //
1368 // These fields are only non-zero when in Chicago mode.
1369 //
1370
1371 if (FatData.ChicagoMode) {
1372
1373 //
1374 // Do a quick check here for Creation and LastAccess
1375 // times that are the same as the LastWriteTime.
1376 //
1377
1378 if (*((UNALIGNED LONG *)&Dirent->CreationTime) ==
1380
1381 DirInfo->CreationTime.QuadPart =
1382
1383 DirInfo->LastWriteTime.QuadPart +
1384 Dirent->CreationMSec * 10 * 1000 * 10;
1385
1386 } else {
1387
1388 //
1389 // Only do the really hard work if this field is non-zero.
1390 //
1391
1392 if (((PUSHORT)Dirent)[8] != 0) {
1393
1394 DirInfo->CreationTime =
1395 FatFatTimeToNtTime( IrpContext,
1397 Dirent->CreationMSec );
1398
1399 } else {
1400
1402 &DirInfo->CreationTime );
1403 }
1404 }
1405
1406 //
1407 // Do a quick check for LastAccessDate.
1408 //
1409
1410 if (*((PUSHORT)&Dirent->LastAccessDate) ==
1411 *((PUSHORT)&Dirent->LastWriteTime.Date)) {
1412
1413 PFAT_TIME WriteTime;
1414
1415 WriteTime = &Dirent->LastWriteTime.Time;
1416
1417 DirInfo->LastAccessTime.QuadPart =
1418 DirInfo->LastWriteTime.QuadPart -
1419 UInt32x32To64(((WriteTime->DoubleSeconds * 2) +
1420 (WriteTime->Minute * 60) +
1421 (WriteTime->Hour * 60 * 60)),
1422 1000 * 1000 * 10);
1423
1424 } else {
1425
1426 //
1427 // Only do the really hard work if this field is non-zero.
1428 //
1429
1430 if (((PUSHORT)Dirent)[9] != 0) {
1431
1432 DirInfo->LastAccessTime =
1433 FatFatDateToNtTime( IrpContext,
1434 Dirent->LastAccessDate );
1435
1436 } else {
1437
1439 &DirInfo->LastAccessTime );
1440 }
1441 }
1442 }
1443}
1444
1445
1446//
1447// Local Support Routine
1448//
1449
1450_Requires_lock_held_(_Global_critical_region_)
1452FatNotifyChangeDirectory (
1453 IN PIRP_CONTEXT IrpContext,
1454 IN PIRP Irp
1455 )
1456
1457/*++
1458
1459Routine Description:
1460
1461 This routine performs the notify change directory operation. It is
1462 responsible for either completing of enqueuing the input Irp.
1463
1464Arguments:
1465
1466 Irp - Supplies the Irp to process
1467
1468Return Value:
1469
1470 NTSTATUS - The return status for the operation
1471
1472--*/
1473
1474{
1477 PVCB Vcb;
1478 PDCB Dcb;
1479 PCCB Ccb;
1482
1484
1485 PAGED_CODE();
1486
1487 //
1488 // Get the current Stack location
1489 //
1490
1492
1493 DebugTrace(+1, Dbg, "FatNotifyChangeDirectory...\n", 0);
1494 DebugTrace( 0, Dbg, " Wait = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
1495 DebugTrace( 0, Dbg, " Irp = %p\n", Irp);
1496 DebugTrace( 0, Dbg, " ->CompletionFilter = %08lx\n", IrpSp->Parameters.NotifyDirectory.CompletionFilter);
1497
1498 //
1499 // Always set the wait flag in the Irp context for the original request.
1500 //
1501
1502 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
1503
1504 //
1505 // Assume we don't complete request.
1506 //
1507
1509
1510 //
1511 // Check on the type of open. We return invalid parameter for all
1512 // but UserDirectoryOpens.
1513 //
1514
1516 &Vcb,
1517 &Dcb,
1518 &Ccb ) != UserDirectoryOpen) {
1519
1521 DebugTrace(-1, Dbg, "FatQueryDirectory -> STATUS_INVALID_PARAMETER\n", 0);
1522
1524
1525 }
1526
1527 //
1528 // Reference our input parameter to make things easier
1529 //
1530
1533
1534 //
1535 // Try to acquire exclusive access to the Dcb and enqueue the Irp to the
1536 // Fsp if we didn't get access
1537 //
1538
1539 if (!FatAcquireExclusiveFcb( IrpContext, Dcb )) {
1540
1541 DebugTrace(0, Dbg, "FatNotifyChangeDirectory -> Cannot Acquire Fcb\n", 0);
1542
1543 Status = FatFsdPostRequest( IrpContext, Irp );
1544
1545 DebugTrace(-1, Dbg, "FatNotifyChangeDirectory -> %08lx\n", Status);
1546 return Status;
1547 }
1548
1549 _SEH2_TRY {
1550
1551 //
1552 // Make sure the Fcb is still good
1553 //
1554
1555 FatVerifyFcb( IrpContext, Dcb );
1556
1557 //
1558 // We need the full name.
1559 //
1560
1561 FatSetFullFileNameInFcb( IrpContext, Dcb );
1562
1563 //
1564 // If the file is marked as DELETE_PENDING then complete this
1565 // request immediately.
1566 //
1567
1568 if (FlagOn( Dcb->FcbState, FCB_STATE_DELETE_ON_CLOSE )) {
1569
1571 }
1572
1573 //
1574 // Call the Fsrtl package to process the request.
1575 //
1576
1578 &Vcb->DirNotifyList,
1579 Ccb,
1580 (PSTRING)&Dcb->FullFileName,
1581 WatchTree,
1582 FALSE,
1584 Irp,
1585 NULL,
1586 NULL );
1587
1589
1591
1592 } _SEH2_FINALLY {
1593
1594 DebugUnwind( FatNotifyChangeDirectory );
1595
1596 FatReleaseFcb( IrpContext, Dcb );
1597
1598 //
1599 // If the dir notify package is holding the Irp, we discard the
1600 // the IrpContext.
1601 //
1602
1603 if (CompleteRequest) {
1604
1605 FatCompleteRequest( IrpContext, FatNull, 0 );
1606 }
1607
1608 DebugTrace(-1, Dbg, "FatNotifyChangeDirectory -> %08lx\n", Status);
1609 } _SEH2_END;
1610
1611 return Status;
1612}
1613
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
PVOID Buffers[0x100]
LONG NTSTATUS
Definition: precomp.h:26
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define CanFsdWait(I)
Definition: cdprocs.h:2001
@ UserDirectoryOpen
Definition: cdprocs.h:576
#define QuadAlign(Ptr)
Definition: cdprocs.h:1572
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define try_return(S)
Definition: cdprocs.h:2179
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
Definition: bufpool.h:45
#define _Requires_lock_held_(lock)
#define UNALIGNED
Definition: crtdefs.h:144
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4140
ULONG32 VBO
Definition: fat.h:38
#define FAT_DIRENT_ATTR_DIRECTORY
Definition: fat.h:372
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define DOS_QM
Definition: env_spec_w32.h:913
#define PagedPool
Definition: env_spec_w32.h:308
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
WCHAR Fat8QMdot3QM[12]
Definition: dirctrl.c:31
VOID FatGetDirTimes(PIRP_CONTEXT IrpContext, PDIRENT Dirent, PFILE_DIRECTORY_INFORMATION DirInfo)
Definition: dirctrl.c:1330
#define Dbg
Definition: dirctrl.c:29
LARGE_INTEGER FatJanOne1980
Definition: fatdata.c:73
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
FAT_DATA FatData
Definition: fatdata.c:56
#define FatNull
Definition: fatdata.h:321
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
#define DIRENT
Definition: fatfs.h:187
#define FatConvertToSharedFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1609
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:414
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
VOID FatStringTo8dot3(_In_ PIRP_CONTEXT IrpContext, _In_ OEM_STRING InputString, _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3)
Definition: namesup.c:79
#define FAT_CREATE_INITIAL_NAME_BUF_SIZE
Definition: fatprocs.h:111
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2983
#define FatIsNameShortOemValid(IRPCONTEXT, NAME, CAN_CONTAIN_WILD_CARDS, PATH_NAME_OK, LEADING_BACKSLASH_OK)
Definition: fatprocs.h:1198
#define FatGenerateFileIdFromDirentAndOffset(Dcb, Dirent, DirentOffset)
Definition: fatprocs.h:3077
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
LARGE_INTEGER FatFatTimeToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_TIME_STAMP FatTime, _In_ UCHAR TenMilliSeconds)
Definition: timesup.c:233
VOID FatFreeStringBuffer(_Inout_ PVOID String)
Definition: strucsup.c:3784
LARGE_INTEGER FatFatDateToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_DATE FatDate)
Definition: timesup.c:171
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define CCB_FLAG_FREE_UNICODE
Definition: fatstruc.h:1260
#define CCB_FLAG_QUERY_TEMPLATE_MIXED
Definition: fatstruc.h:1303
#define CCB_FLAG_SKIP_SHORT_NAME_COMPARE
Definition: fatstruc.h:1253
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193
#define CCB_FLAG_MATCH_ALL
Definition: fatstruc.h:1252
#define CCB_FLAG_FREE_OEM_BEST_FIT
Definition: fatstruc.h:1259
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2299
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
Definition: fltkernel.h:1129
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2295
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG CompletionFilter
Definition: fltkernel.h:2243
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN WatchTree
Definition: fltkernel.h:2241
struct _FILE_BOTH_DIR_INFORMATION * PFILE_BOTH_DIR_INFORMATION
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
struct _FILE_NAMES_INFORMATION * PFILE_NAMES_INFORMATION
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
const GLubyte * c
Definition: glext.h:8905
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
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI RtlFreeOemString(POEM_STRING OemString)
struct _FILE_FULL_DIRECTORY_INFORMATION * PFILE_FULL_DIR_INFORMATION
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
struct _FILE_DIRECTORY_INFORMATION * PFILE_DIRECTORY_INFORMATION
#define NOTHING
Definition: input_list.c:10
#define UInt32x32To64(a, b)
Definition: intsafe.h:252
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define c
Definition: ke_i.h:80
#define PCHAR
Definition: match.c:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
#define _Function_class_(x)
Definition: ms_sal.h:2946
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
DRIVER_DISPATCH(nfs41_FsdDispatch)
_Use_decl_annotations_ NTSTATUS NTAPI RtlOemToUnicodeN(_Out_ PWCHAR UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH OemString, _In_ ULONG OemSize)
Definition: nlsboot.c:282
WCHAR * PWCH
Definition: ntbasedef.h:410
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
VOID NTAPI FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
Definition: notify.c:1487
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define STATUS_UNMAPPABLE_CHARACTER
Definition: ntstatus.h:590
#define L(x)
Definition: ntvdm.h:50
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
#define Vcb
Definition: cdprocs.h:1415
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
Definition: cdstruc.h:1067
BOOLEAN ChicagoMode
Definition: fatstruc.h:87
Definition: fat.h:265
USHORT Hour
Definition: fat.h:269
USHORT DoubleSeconds
Definition: fat.h:267
USHORT Minute
Definition: fat.h:268
Definition: cdstruc.h:902
LONGLONG CreationTime
Definition: cdstruc.h:1030
ULONG Flags
Definition: ntfs.h:536
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
LARGE_INTEGER EndOfFile
Definition: winternl.h:520
LARGE_INTEGER CreationTime
Definition: winternl.h:516
LARGE_INTEGER LastWriteTime
Definition: winternl.h:518
LARGE_INTEGER LastAccessTime
Definition: winternl.h:517
LARGE_INTEGER AllocationSize
Definition: winternl.h:521
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3985 NotifyDirectory
struct _IO_STACK_LOCATION::@3978::@3984 QueryDirectory
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: cdstruc.h:498
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
ULONG CLONG
Definition: umtypes.h:126
STRING OEM_STRING
Definition: umtypes.h:203
LONGLONG QuadPart
Definition: typedefs.h:114
#define SL_WATCH_TREE
Definition: iotypes.h:1839
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
struct _FILE_ID_BOTH_DIR_INFORMATION * PFILE_ID_BOTH_DIR_INFORMATION
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
struct _FILE_ID_FULL_DIR_INFORMATION * PFILE_ID_FULL_DIR_INFORMATION
#define SL_RESTART_SCAN
Definition: iotypes.h:1835
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define RtlOemStringToCountedUnicodeSize(STRING)
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180