ReactOS 0.4.16-dev-401-g45b008d
fsctl.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: fsctl.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "ext2fs.h"
13
14/* GLOBALS ***************************************************************/
15
17
18/* DEFINITIONS *************************************************************/
19
20#ifdef ALLOC_PRAGMA
21#pragma alloc_text(PAGE, Ext2IsHandleCountZero)
22#pragma alloc_text(PAGE, Ext2LockVcb)
23#pragma alloc_text(PAGE, Ext2LockVolume)
24#pragma alloc_text(PAGE, Ext2UnlockVcb)
25#pragma alloc_text(PAGE, Ext2UnlockVolume)
26#pragma alloc_text(PAGE, Ext2AllowExtendedDasdIo)
27#pragma alloc_text(PAGE, Ext2GetRetrievalPointerBase)
28#pragma alloc_text(PAGE, Ext2QueryExtentMappings)
29#pragma alloc_text(PAGE, Ext2QueryRetrievalPointers)
30#pragma alloc_text(PAGE, Ext2GetRetrievalPointers)
31#pragma alloc_text(PAGE, Ext2UserFsRequest)
32#pragma alloc_text(PAGE, Ext2IsMediaWriteProtected)
33#pragma alloc_text(PAGE, Ext2MountVolume)
34#pragma alloc_text(PAGE, Ext2PurgeVolume)
35#pragma alloc_text(PAGE, Ext2PurgeFile)
36#pragma alloc_text(PAGE, Ext2DismountVolume)
37#pragma alloc_text(PAGE, Ext2IsVolumeMounted)
38#pragma alloc_text(PAGE, Ext2VerifyVolume)
39#pragma alloc_text(PAGE, Ext2FileSystemControl)
40#endif
41
42
43VOID
45 IN PVPB Vpb,
46 IN USHORT Flag )
47{
49
51 Vpb->Flags |= Flag;
53}
54
55VOID
57 IN PVPB Vpb,
58 IN USHORT Flag )
59{
61
63 Vpb->Flags &= ~Flag;
65}
66
69{
72
73 for ( List = Vcb->FcbList.Flink;
74 List != &Vcb->FcbList;
75 List = List->Flink ) {
76
78
80 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
81
82 DEBUG(DL_INF, ( "Ext2IsHandleCountZero: Inode:%xh File:%S OpenHandleCount=%xh\n",
83 Fcb->Inode->i_ino, Fcb->Mcb->ShortName.Buffer, Fcb->OpenHandleCount));
84
85 if (Fcb->OpenHandleCount) {
86 return FALSE;
87 }
88 }
89
90 return TRUE;
91}
92
96{
98
99 _SEH2_TRY {
100
101 if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
102 DEBUG(DL_INF, ( "Ext2LockVolume: Volume is already locked.\n"));
105 }
106
107 if (Vcb->OpenHandleCount > (ULONG)(FileObject ? 1 : 0)) {
108 DEBUG(DL_INF, ( "Ext2LockVcb: There are still opened files.\n"));
109
112 }
113
115 DEBUG(DL_INF, ( "Ext2LockVcb: Thare are still opened files.\n"));
116
119 }
120
123 Vcb->LockFile = FileObject;
124
125 DEBUG(DL_INF, ( "Ext2LockVcb: Volume locked.\n"));
126
127 } _SEH2_FINALLY {
128 // Nothing
129 } _SEH2_END;
130
131 return Status;
132}
133
134
137{
142 BOOLEAN VcbResourceAcquired = FALSE;
143
144 _SEH2_TRY {
145
146 ASSERT(IrpContext != NULL);
147
148 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
149 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
150
151 DeviceObject = IrpContext->DeviceObject;
152
154
155 //
156 // This request is not allowed on the main device object
157 //
161 }
162
163 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
164
165 ASSERT(Vcb != NULL);
166
167 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
168 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
169
171
172 IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
173
174#if (_WIN32_WINNT >= 0x0500)
176#endif
178 &Vcb->MainResource,
179 TRUE );
180
181 VcbResourceAcquired = TRUE;
182
183 /* flush dirty data before locking the volume */
184 if (!IsVcbReadOnly(Vcb)) {
185 Ext2FlushFiles(IrpContext, Vcb, FALSE);
186 Ext2FlushVolume(IrpContext, Vcb, FALSE);
187 }
188
190
191 } _SEH2_FINALLY {
192
193 if (VcbResourceAcquired) {
194 ExReleaseResourceLite(&Vcb->MainResource);
195 }
196
197 if (!IrpContext->ExceptionInProgress) {
198 Ext2CompleteIrpContext(IrpContext, Status);
199 }
200 } _SEH2_END;
201
202 return Status;
203}
204
208{
210
211 _SEH2_TRY {
212
213 if (FileObject && FileObject->FsContext != Vcb) {
216 }
217
218 if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
219 DEBUG(DL_ERR, ( ": Ext2UnlockVcb: Volume is not locked.\n"));
222 }
223
224 if (Vcb->LockFile == FileObject) {
227 DEBUG(DL_INF, ( "Ext2UnlockVcb: Volume unlocked.\n"));
229 } else {
231 }
232
233 } _SEH2_FINALLY {
234 // Nothing
235 } _SEH2_END;
236
237 return Status;
238}
239
242 IN PEXT2_IRP_CONTEXT IrpContext
243)
244{
249 BOOLEAN VcbResourceAcquired = FALSE;
250
251 _SEH2_TRY {
252
253 ASSERT(IrpContext != NULL);
254 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
255 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
256
257 DeviceObject = IrpContext->DeviceObject;
258 IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
259
260 //
261 // This request is not allowed on the main device object
262 //
266 }
267
268 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
269 ASSERT(Vcb != NULL);
270 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
271 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
272
274 &Vcb->MainResource,
275 TRUE );
276 VcbResourceAcquired = TRUE;
277
279
280 } _SEH2_FINALLY {
281
282 if (VcbResourceAcquired) {
283 ExReleaseResourceLite(&Vcb->MainResource);
284 }
285
286 if (!IrpContext->ExceptionInProgress) {
287 Ext2CompleteIrpContext(IrpContext, Status);
288 }
289 } _SEH2_END;
290
291 return Status;
292}
293
294
297{
299 PIRP Irp;
301
302#ifndef __REACTOS__
303 PVPB NewVpb = NULL;
304#endif
306 PLIST_ENTRY ListEntry;
307
308 ULONG InputLength = 0;
311 BOOLEAN GlobalResourceAcquired = FALSE;
312
314
315 _SEH2_TRY {
316
317 Irp = IrpContext->Irp;
319
323 }
324
325 if (!SeSinglePrivilegeCheck(Privilege, Irp->RequestorMode)) {
328 }
329
330
331#ifndef _GNU_NTIFS_
332 InputLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
333#else
334 InputLength = ((PEXTENDED_IO_STACK_LOCATION)(IrpSp))->
335 Parameters.FileSystemControl.InputBufferLength;
336#endif
337
338#if defined(_WIN64)
339 if (IoIs32bitProcess(Irp)) {
340 if (InputLength != sizeof(UINT32)) {
343 }
344 Handle = (HANDLE) LongToHandle( (*(PUINT32)Irp->AssociatedIrp.SystemBuffer) );
345 } else
346#endif
347 {
348 if (InputLength != sizeof(HANDLE)) {
351 }
352 Handle = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;
353 }
354
356 0,
359 (void **)&FileObject,
360 NULL );
361
362 if (!NT_SUCCESS(Status)) {
364 } else {
365 DeviceObject = FileObject->DeviceObject;
367 }
368
370 GlobalResourceAcquired = TRUE;
371
372 ListEntry = Ext2Global->VcbList.Flink;
373 while (ListEntry != &Ext2Global->VcbList) {
374
375 PEXT2_VCB Vcb = CONTAINING_RECORD(ListEntry, EXT2_VCB, Next);
376 ListEntry = ListEntry->Flink;
377
378 DEBUG(DL_DBG, ( "Ext2InvalidateVolumes: Vcb=%xh Vcb->Vpb=%xh "
379 "Blink = %p &Vcb->Next = %p\n",
380 Vcb, Vcb->Vpb, ListEntry->Blink, &Vcb->Next));
381
382 if (Vcb->Vpb && (Vcb->Vpb->RealDevice == DeviceObject)) {
383
384 DEBUG(DL_DBG, ( "Ext2InvalidateVolumes: Got Vcb=%xh Vcb->Vpb=%xh "
385 "Blink = %p &Vcb->Next = %p\n",
386 Vcb, Vcb->Vpb, ListEntry->Blink, &Vcb->Next));
387 /* dismount the volume */
388 Ext2CheckDismount(IrpContext, Vcb, FALSE);
389 }
390 }
391
392 } _SEH2_FINALLY {
393
394 if (GlobalResourceAcquired) {
396 }
397
398 if (!IrpContext->ExceptionInProgress) {
399 Ext2CompleteIrpContext(IrpContext, Status);
400 }
401 } _SEH2_END;
402
403 return Status;
404}
405
408{
413
414 IrpSp = IoGetCurrentIrpStackLocation(IrpContext->Irp);
415
416 Vcb = (PEXT2_VCB) IrpSp->FileObject->FsContext;
417 Ccb = (PEXT2_CCB) IrpSp->FileObject->FsContext2;
418
419 ASSERT(Vcb != NULL);
420
421 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
422 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
423
425
426 if (Ccb) {
429 } else {
431 }
432
433 Ext2CompleteIrpContext(IrpContext, status);
434 return status;
435}
436
437/*
438 * Ext2OplockRequest
439 *
440 * oplock requests handler routine
441 *
442 * Arguments:
443 * IrpContext: the ext2 irp context
444 *
445 * Return Value:
446 * NTSTATUS: The return status for the operation
447 *
448 */
449
452 IN PEXT2_IRP_CONTEXT IrpContext
453)
454{
456
457 ULONG FsCtrlCode;
460
461 PIRP Irp = NULL;
464
468
469 ULONG OplockCount = 0;
470
471 BOOLEAN VcbResourceAcquired = FALSE;
472 BOOLEAN FcbResourceAcquired = FALSE;
473
474 ASSERT(IrpContext);
475
476 _SEH2_TRY {
477
478 Irp = IrpContext->Irp;
479 ASSERT(Irp);
480
482 ASSERT(IrpSp);
484
485 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
486 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
487
488 DeviceObject = IrpContext->DeviceObject;
489
490 //
491 // This request is not allowed on the main device object
492 //
496 }
497
498 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
499
500 ASSERT(Vcb != NULL);
501
502 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
503 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
504
506
507 FileObject = IrpContext->FileObject;
508
509 Fcb = (PEXT2_FCB) FileObject->FsContext;
510
511 //
512 // This request is not allowed on volumes
513 //
514
515 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
518 }
519
521 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
522
523 if (IsFlagOn(Fcb->Mcb->Flags, MCB_FILE_DELETED)) {
526 }
527
528 Ccb = (PEXT2_CCB) FileObject->FsContext2;
529 if (Ccb == NULL) {
532 }
533
534
536 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
537
538 FsCtrlCode = EIrpSp->Parameters.FileSystemControl.FsControlCode;
539
540 switch (FsCtrlCode) {
541
545
546 VcbResourceAcquired =
548 &Vcb->MainResource,
549 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) );
550
551 ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
552
553 FcbResourceAcquired =
556 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
557
558 if (FsCtrlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2) {
559 OplockCount = (ULONG) FsRtlAreThereCurrentFileLocks(&Fcb->FileLockAnchor);
560 } else {
561 OplockCount = Fcb->OpenHandleCount;
562 }
563
564 break;
565
570
571 FcbResourceAcquired =
574 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
575
576 break;
577
578 default:
579
580 Ext2BugCheck(EXT2_BUGCHK_FSCTL, FsCtrlCode, 0, 0);
581 }
582
583
584 //
585 // Call the FsRtl routine to grant/acknowledge oplock.
586 //
587
588 Status = FsRtlOplockFsctrl( &Fcb->Oplock,
589 Irp,
590 OplockCount );
591
592 //
593 // Set the flag indicating if Fast I/O is possible
594 //
595
596 Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
597 IrpContext->Irp = NULL;
598
599 } _SEH2_FINALLY {
600
601 if (FcbResourceAcquired) {
603 }
604
605 if (VcbResourceAcquired) {
606 ExReleaseResourceLite(&Vcb->MainResource);
607 }
608
610 Ext2CompleteIrpContext(IrpContext, Status);
611 }
612 } _SEH2_END;
613
614 return Status;
615}
616
619 IN PEXT2_IRP_CONTEXT IrpContext
620)
621{
623 PIRP Irp;
626
627 _SEH2_TRY {
628
629 Irp = IrpContext->Irp;
631
632 //
633 // Get a pointer to the output buffer. Look at the system buffer field in th
634 // irp first. Then the Irp Mdl.
635 //
636
637 if (Irp->AssociatedIrp.SystemBuffer != NULL) {
638
639 VolumeState = Irp->AssociatedIrp.SystemBuffer;
640
641 } else if (Irp->MdlAddress != NULL) {
642
644
645 } else {
646
649 }
650
651 if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) {
654 }
655
656 *VolumeState = 0;
657
658 } _SEH2_FINALLY {
659
660 if (!IrpContext->ExceptionInProgress) {
661 Ext2CompleteIrpContext(IrpContext, status);
662 }
663 } _SEH2_END;
664
665 return status;
666}
667
668
671 IN PEXT2_IRP_CONTEXT IrpContext,
674 IN PLARGE_INTEGER RequestVbn,
675 OUT PLARGE_INTEGER * pMappedRuns
676)
677{
678 PLARGE_INTEGER MappedRuns = NULL;
679 PLARGE_INTEGER PartialRuns = NULL;
680
681 PEXT2_EXTENT Chain = NULL;
683
684 LONGLONG Vbn = 0;
685 ULONG Length = 0;
686 ULONG i = 0;
687
689
690 _SEH2_TRY {
691
692 /* now building all the request extents */
693 while (Vbn < RequestVbn->QuadPart) {
694
695 Length = 0x80000000; /* 2g bytes */
696 if (RequestVbn->QuadPart < Vbn + Length) {
697 Length = (ULONG)(RequestVbn->QuadPart - Vbn);
698 }
699
700 /* build extents for sub-range */
701 Extent = NULL;
703 IrpContext,
704 Vcb,
705 Fcb->Mcb,
706 Vbn,
707 Length,
708 FALSE,
709 &Extent);
710
711 if (!NT_SUCCESS(Status)) {
713 }
714
715 if (Chain) {
716 Ext2JointExtents(Chain, Extent);
717 } else {
718 Chain = Extent;
719 }
720
721 /* allocate extent array */
722 PartialRuns = Ext2AllocatePool(
724 (Ext2CountExtents(Chain) + 2) *
725 (2 * sizeof(LARGE_INTEGER)),
726 'RE2E');
727
728 if (PartialRuns == NULL) {
731 }
732 RtlZeroMemory( PartialRuns,
733 (Ext2CountExtents(Chain) + 2) *
734 (2 * sizeof(LARGE_INTEGER)));
735
736 if (MappedRuns) {
737 RtlMoveMemory(PartialRuns,
738 MappedRuns,
739 i * 2 * sizeof(LARGE_INTEGER));
740 Ext2FreePool(MappedRuns, 'RE2E');
741 }
742 MappedRuns = PartialRuns;
743
744 /* walk all the Mcb runs in Extent */
745 for (; Extent != NULL; Extent = Extent->Next) {
746 MappedRuns[i*2 + 0].QuadPart = Vbn + Extent->Offset;
747 MappedRuns[i*2 + 1].QuadPart = Extent->Lba;
748 i = i+1;
749 }
750
751 Vbn = Vbn + Length;
752 }
753
754 *pMappedRuns = MappedRuns;
755
756 } _SEH2_FINALLY {
757
759 if (MappedRuns) {
760 Ext2FreePool(MappedRuns, 'RE2E');
761 }
762 *pMappedRuns = NULL;
763 }
764
765 if (Chain) {
767 }
768 } _SEH2_END;
769
770 return Status;
771}
772
775 IN PEXT2_IRP_CONTEXT IrpContext
776)
777{
778 PIRP Irp = NULL;
781
784
788
789 PLARGE_INTEGER RequestVbn;
790 PLARGE_INTEGER * pMappedRuns;
791
792 ULONG InputSize;
793 ULONG OutputSize;
794
796
797 BOOLEAN FcbResourceAcquired = FALSE;
798
799 _SEH2_TRY {
800
801 ASSERT(IrpContext);
802 Irp = IrpContext->Irp;
803 ASSERT(Irp);
804
807 ASSERT(IrpSp);
808
809 InputSize = EIrpSp->Parameters.FileSystemControl.InputBufferLength;
810 OutputSize = EIrpSp->Parameters.FileSystemControl.OutputBufferLength;
811
812 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
813 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
814
815 DeviceObject = IrpContext->DeviceObject;
816
817 DbgBreak();
818
819 /* This request is not allowed on the main device object */
823 }
824
825 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
826 ASSERT(Vcb != NULL);
827 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
828 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
830
831 FileObject = IrpContext->FileObject;
832 Fcb = (PEXT2_FCB) FileObject->FsContext;
833
834 /* check Fcb is valid or not */
835 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
838 }
839
841 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
842 if (IsFlagOn(Fcb->Mcb->Flags, MCB_FILE_DELETED)) {
845 }
846
847 Ccb = (PEXT2_CCB) FileObject->FsContext2;
848 if (Ccb == NULL) {
851 }
852
854 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
855
856 /* Is requstor in kernel and Fcb a paging file ? */
857 if (Irp->RequestorMode != KernelMode ||
859 InputSize != sizeof(LARGE_INTEGER) ||
860 OutputSize != sizeof(PVOID)) {
863 }
864
869 }
870 FcbResourceAcquired = TRUE;
871
872 RequestVbn = EIrpSp->Parameters.FileSystemControl.Type3InputBuffer;
873 pMappedRuns = Irp->UserBuffer;
874
875 DbgBreak();
876
877 /* request size beyonds whole file size */
878 if (RequestVbn->QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
881 }
882
884 IrpContext,
885 Vcb,
886 Fcb,
887 RequestVbn,
888 pMappedRuns
889 );
890
891 } _SEH2_FINALLY {
892
893 if (FcbResourceAcquired) {
895 }
896
899 Status = Ext2QueueRequest(IrpContext);
900 } else {
901 Ext2CompleteIrpContext(IrpContext, Status);
902 }
903 }
904 } _SEH2_END;
905
906 return Status;
907}
908
909
912 IN PEXT2_IRP_CONTEXT IrpContext
913)
914{
915 PIRP Irp = NULL;
918
921
925
928
929 PEXT2_EXTENT Chain = NULL;
931
932 LONGLONG Vbn = 0;
933 ULONG Length = 0;
934 ULONG i = 0;
935
936 ULONG UsedSize = 0;
937 ULONG InputSize;
938 ULONG OutputSize;
939
941
942 BOOLEAN FcbResourceAcquired = FALSE;
943
944 _SEH2_TRY {
945
946 ASSERT(IrpContext);
947 Irp = IrpContext->Irp;
948 ASSERT(Irp);
949
952 ASSERT(IrpSp);
953
954 InputSize = EIrpSp->Parameters.FileSystemControl.InputBufferLength;
955 OutputSize = EIrpSp->Parameters.FileSystemControl.OutputBufferLength;
956
957 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
958 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
959
960 DeviceObject = IrpContext->DeviceObject;
961
962 /* This request is not allowed on the main device object */
966 }
967
968 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
969 ASSERT(Vcb != NULL);
970 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
971 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
973
974 FileObject = IrpContext->FileObject;
975 Fcb = (PEXT2_FCB) FileObject->FsContext;
976
977 /* check Fcb is valid or not */
978 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
981 }
982
984 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
985
986 if (IsFlagOn(Fcb->Mcb->Flags, MCB_FILE_DELETED)) {
989 }
990
991 Ccb = (PEXT2_CCB) FileObject->FsContext2;
992 if (Ccb == NULL) {
995 }
996
998 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
999
1000 if (InputSize < sizeof(STARTING_VCN_INPUT_BUFFER) ||
1001 OutputSize < sizeof(RETRIEVAL_POINTERS_BUFFER) ) {
1004 }
1005
1010 }
1011 FcbResourceAcquired = TRUE;
1012
1014 EIrpSp->Parameters.FileSystemControl.Type3InputBuffer;
1016
1017 /* probe user buffer */
1018
1019 _SEH2_TRY {
1020 if (Irp->RequestorMode != KernelMode) {
1021 ProbeForRead (SVIB, InputSize, sizeof(UCHAR));
1022 ProbeForWrite(RPSB, OutputSize, sizeof(UCHAR));
1023 }
1026 } _SEH2_END;
1027
1028 if (!NT_SUCCESS(Status)) {
1030 }
1031
1032 UsedSize = FIELD_OFFSET(RETRIEVAL_POINTERS_BUFFER, Extents[0]);
1033
1034 /* request size beyonds whole file size ? */
1035 DEBUG(DL_DBG, ("Ext2GetRetrievalPointers: Startin from Vbn: %I64xh\n",
1036 SVIB->StartingVcn.QuadPart));
1037 Vbn = (SVIB->StartingVcn.QuadPart << BLOCK_BITS);
1038 if (Vbn >= Fcb->Header.AllocationSize.QuadPart ) {
1041 }
1042
1043 /* now building all the request extents */
1044 while (Vbn < Fcb->Header.AllocationSize.QuadPart) {
1045
1046 ASSERT(Chain == NULL);
1047 Length = 0x80000000; /* 2g bytes */
1048 if (Fcb->Header.AllocationSize.QuadPart < Vbn + Length) {
1049 Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - Vbn);
1050 }
1051
1052 /* build extents for sub-range */
1054 IrpContext,
1055 Vcb,
1056 Fcb->Mcb,
1057 Vbn,
1058 Length,
1059 FALSE,
1060 &Chain);
1061
1062 if (!NT_SUCCESS(Status)) {
1063 DbgBreak();
1065 }
1066
1067 /* fill user buffer of RETRIEVAL_POINTERS_BUFFER */
1068 Extent = Chain;
1069 while (Extent) {
1070
1071 DEBUG(DL_MAP, ("Ext2GetRetrievalPointers: %wZ %d Vbn = %I64xh Lbn = %I64xh\n",
1072 &Fcb->Mcb->FullName, i,
1073 ((Vbn + Extent->Offset) >> BLOCK_BITS),
1074 Extent->Lba));
1075
1076 RPSB->Extents[i].Lcn.QuadPart = (Extent->Lba >> BLOCK_BITS);
1077 RPSB->Extents[i].NextVcn.QuadPart = ((Vbn + Extent->Offset + Extent->Length) >> BLOCK_BITS);
1078 if (i == 0) {
1079 RPSB->StartingVcn.QuadPart = ((Vbn + Extent->Offset) >> BLOCK_BITS);
1080 } else {
1081 ASSERT(RPSB->Extents[i-1].NextVcn.QuadPart == ((Vbn + Extent->Offset) >> BLOCK_BITS));
1082 }
1083 if (UsedSize + sizeof(RETRIEVAL_POINTERS_BUFFER) > OutputSize) {
1086 }
1087 UsedSize += sizeof(LARGE_INTEGER) * 2;
1088 Irp->IoStatus.Information = (ULONG_PTR)UsedSize;
1089 RPSB->ExtentCount = ++i;
1090 Extent = Extent->Next;
1091 }
1092
1093 if (Chain) {
1095 Chain = NULL;
1096 }
1097
1098 Vbn = Vbn + Length;
1099 }
1100
1101#if 0
1102 {
1103 NTSTATUS _s;
1104 ULONG _i = 0;
1105 LARGE_INTEGER RequestVbn = Fcb->Header.AllocationSize;
1106 PLARGE_INTEGER MappedRuns = NULL;
1107
1109 IrpContext,
1110 Vcb,
1111 Fcb,
1112 &RequestVbn,
1113 &MappedRuns
1114 );
1115 if (!NT_SUCCESS(_s) || NULL == MappedRuns) {
1116 DbgBreak();
1117 goto exit_to_get_rps;
1118 }
1119
1120 while (MappedRuns[_i*2 + 0].QuadPart != 0 ||
1121 MappedRuns[_i*2 + 1].QuadPart != 0 ) {
1122 DEBUG(DL_MAP, ("Ext2QueryExtentMappings: %wZ %d Vbn = %I64xh Lbn = %I64xh\n",
1123 &Fcb->Mcb->FullName, _i,
1124 MappedRuns[_i*2 + 0].QuadPart,
1125 MappedRuns[_i*2 + 1].QuadPart));
1126 _i++;
1127 }
1128
1129exit_to_get_rps:
1130
1131 if (MappedRuns) {
1132 Ext2FreePool(MappedRuns, 'RE2E');
1133 }
1134 }
1135#endif
1136
1137 } _SEH2_FINALLY {
1138
1139 if (FcbResourceAcquired) {
1141 }
1142
1143 if (Chain) {
1145 }
1146
1149 Status = Ext2QueueRequest(IrpContext);
1150 } else {
1151 Ext2CompleteIrpContext(IrpContext, Status);
1152 }
1153 }
1154 } _SEH2_END;
1155
1156 return Status;
1157}
1158
1161 IN PEXT2_IRP_CONTEXT IrpContext
1162)
1163{
1164 PIRP Irp = NULL;
1167
1170
1171 PEXT2_VCB Vcb = NULL;
1172 PEXT2_FCB Fcb = NULL;
1173 PEXT2_CCB Ccb = NULL;
1174
1175 PLARGE_INTEGER FileAreaOffset;
1176
1177 ULONG OutputSize;
1178
1180
1181 BOOLEAN FcbResourceAcquired = FALSE;
1182
1183 _SEH2_TRY {
1184
1185 ASSERT(IrpContext);
1186 Irp = IrpContext->Irp;
1187 ASSERT(Irp);
1188
1191 ASSERT(IrpSp);
1192
1193 OutputSize = EIrpSp->Parameters.FileSystemControl.OutputBufferLength;
1194
1195 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1196 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1197
1198 DeviceObject = IrpContext->DeviceObject;
1199
1200 /* This request is not allowed on the main device object */
1204 }
1205
1206 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
1207 ASSERT(Vcb != NULL);
1208 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
1209 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
1211
1212 FileObject = IrpContext->FileObject;
1213 Fcb = (PEXT2_FCB) FileObject->FsContext;
1214
1215 /* check Fcb is valid or not */
1216 if (Fcb == NULL || Fcb->Identifier.Type == EXT2VCB) {
1219 }
1220
1222 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
1223
1224 if (IsFlagOn(Fcb->Mcb->Flags, MCB_FILE_DELETED)) {
1227 }
1228
1229 Ccb = (PEXT2_CCB) FileObject->FsContext2;
1230 if (Ccb == NULL) {
1233 }
1234
1236 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
1237
1238 if (OutputSize < sizeof(LARGE_INTEGER)) {
1241 }
1242
1247 }
1248 FcbResourceAcquired = TRUE;
1249
1250 FileAreaOffset = (PLARGE_INTEGER) Ext2GetUserBuffer(Irp);
1251
1252 /* probe user buffer */
1253
1254 _SEH2_TRY {
1255 if (Irp->RequestorMode != KernelMode) {
1256 ProbeForWrite(FileAreaOffset, OutputSize, sizeof(UCHAR));
1257 }
1258
1260
1262 } _SEH2_END;
1263
1264 if (!NT_SUCCESS(Status)) {
1266 }
1267
1268 DEBUG(DL_DBG, ("Ext2GetRetrievalPointerBase: FileAreaOffset is 0.\n"));
1269
1270 FileAreaOffset->QuadPart = 0; // sector offset to the first allocatable unit on the filesystem
1271
1272 Irp->IoStatus.Information = sizeof(LARGE_INTEGER);
1273
1274 } _SEH2_FINALLY {
1275
1276 if (FcbResourceAcquired) {
1278 }
1279
1282 Status = Ext2QueueRequest(IrpContext);
1283 } else {
1284 Ext2CompleteIrpContext(IrpContext, Status);
1285 }
1286 }
1287 } _SEH2_END;
1288
1289 return Status;
1290}
1291
1296)
1297{
1299
1300 if (!RDB) {
1302 goto out;
1303 }
1304
1305 if (InputBufferLength < sizeof(REPARSE_DATA_BUFFER)) {
1307 goto out;
1308 }
1309
1310 if (InputBufferLength < RDB->ReparseDataLength) {
1312 goto out;
1313 }
1314
1315 if (RDB->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
1317 goto out;
1318 }
1319
1320 if ((PUCHAR)RDB->SymbolicLinkReparseBuffer.PathBuffer
1321 + RDB->SymbolicLinkReparseBuffer.SubstituteNameOffset
1322 + RDB->SymbolicLinkReparseBuffer.SubstituteNameLength
1323 > (PUCHAR)RDB + InputBufferLength ) {
1325 goto out;
1326 }
1327
1328 if ((PUCHAR)RDB->SymbolicLinkReparseBuffer.PathBuffer
1329 + RDB->SymbolicLinkReparseBuffer.PrintNameOffset
1330 + RDB->SymbolicLinkReparseBuffer.PrintNameLength
1331 > (PUCHAR)RDB + InputBufferLength) {
1333 goto out;
1334 }
1335
1336 if (RDB->SymbolicLinkReparseBuffer.Flags != SYMLINK_FLAG_RELATIVE) {
1338 goto out;
1339 }
1340
1341out:
1342 return Status;
1343}
1344
1345VOID
1347{
1348 ASSERT(FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.SubstituteNameOffset) ==
1350 RDB->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1351 RDB->ReparseDataLength = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
1352 FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
1353 PathBufferLength * sizeof(WCHAR);
1354 RDB->Reserved = 0;
1355 RDB->SymbolicLinkReparseBuffer.SubstituteNameOffset = PathBufferLength;
1356 RDB->SymbolicLinkReparseBuffer.SubstituteNameLength = PathBufferLength;
1357 RDB->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
1358 RDB->SymbolicLinkReparseBuffer.PrintNameLength = PathBufferLength;
1359 RDB->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;
1360 RtlZeroMemory(&RDB->SymbolicLinkReparseBuffer.PathBuffer, PathBufferLength * 2);
1361}
1362
1365 IN PEXT2_IRP_CONTEXT IrpContext,
1368 IN PVOID Buffer,
1369 IN ULONG Size,
1371 )
1372{
1373 return Ext2ReadInode ( IrpContext,
1374 Vcb,
1375 Mcb,
1376 0,
1377 Buffer,
1378 Size,
1379 FALSE,
1380 BytesRead);
1381}
1382
1383
1384
1387{
1388 PIRP Irp = NULL;
1391
1393
1394 PEXT2_VCB Vcb = NULL;
1395 PEXT2_CCB Ccb = NULL;
1396 PEXT2_MCB Mcb = NULL;
1397
1399 BOOLEAN MainResourceAcquired = FALSE;
1400
1403 ULONG BytesRead = 0;
1404
1406
1407 UNICODE_STRING UniName;
1409
1410 PCHAR OemNameBuffer = NULL;
1411 int OemNameLength = 0, i;
1412
1413 Ccb = IrpContext->Ccb;
1414 ASSERT(Ccb != NULL);
1416 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
1417 DeviceObject = IrpContext->DeviceObject;
1418 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
1419 Mcb = IrpContext->Fcb->Mcb;
1420 Irp = IrpContext->Irp;
1422
1423 _SEH2_TRY {
1424
1425 if (!Mcb || !IsInodeSymLink(&Mcb->Inode) ||
1429 }
1430
1431 OutputBuffer = (PVOID)Irp->AssociatedIrp.SystemBuffer;
1433
1435 if (!RDB) {
1438 }
1442 }
1443
1444 OemNameLength = (ULONG)Mcb->Inode.i_size;
1445 if (OemNameLength > USHRT_MAX) {
1448 }
1449 OemName.Length = (USHORT)OemNameLength;
1450 OemName.MaximumLength = OemNameLength + 1;
1451 OemNameBuffer = OemName.Buffer = Ext2AllocatePool(NonPagedPool,
1452 OemName.MaximumLength,
1453 'NL2E');
1454 if (!OemNameBuffer) {
1457 }
1458
1459 Status = Ext2ReadSymlink(IrpContext,
1460 Vcb,
1461 Mcb,
1462 OemNameBuffer,
1463 OemNameLength,
1464 &BytesRead
1465 );
1466 OemName.Buffer[OemName.Length] = '\0';
1467 for (i = 0;i < OemName.Length;i++) {
1468 if (OemName.Buffer[i] == '/') {
1469 OemName.Buffer[i] = '\\';
1470 }
1471 }
1472
1473 if (OutputBufferLength - FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) > USHRT_MAX) {
1474 UniName.Length = USHRT_MAX;
1475 } else {
1476 UniName.Length = (USHORT)OutputBufferLength - FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer);
1477 }
1478 UniName.MaximumLength = UniName.Length;
1480 Irp->IoStatus.Information = FIELD_OFFSET(REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) + 2 * UniName.Length;
1481 if (UniName.MaximumLength < 2*UniName.Length) {
1484 }
1485
1486 Ext2InitializeReparseData(RDB, UniName.Length);
1487 UniName.Buffer = RDB->SymbolicLinkReparseBuffer.PathBuffer;
1488 /*
1489 (PWCHAR)((PUCHAR)&
1490 + RDB->SymbolicLinkReparseBuffer.SubstituteNameOffset);
1491 */
1492 Ext2OEMToUnicode(Vcb, &UniName, &OemName);
1494 RDB->SymbolicLinkReparseBuffer.SubstituteNameOffset,
1495 UniName.Buffer, UniName.Length);
1496
1498
1499 } _SEH2_FINALLY {
1500
1501 if (OemNameBuffer) {
1502 Ext2FreePool(OemNameBuffer, 'NL2E');
1503 }
1504
1507 Status = Ext2QueueRequest(IrpContext);
1508 } else {
1509 Ext2CompleteIrpContext(IrpContext, Status);
1510 }
1511 }
1512 } _SEH2_END;
1513
1514 return Status;
1515}
1516
1517
1520 IN PEXT2_IRP_CONTEXT IrpContext,
1523 IN PVOID Buffer,
1524 IN ULONG Size,
1526)
1527{
1529 PUCHAR Data = (PUCHAR)(&Mcb->Inode.i_block[0]);
1530
1531 if (Size >= EXT2_LINKLEN_IN_INODE) {
1532
1533 /* initialize inode i_block[] */
1534 if (0 == Mcb->Inode.i_blocks) {
1536 ClearFlag(Mcb->Inode.i_flags, EXT4_EXTENTS_FL);
1537 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
1538 }
1539
1540 Status = Ext2WriteInode(IrpContext, Vcb, Mcb,
1541 0, Buffer, Size,
1543 if (!NT_SUCCESS(Status)) {
1544 goto out;
1545 }
1546
1547 } else {
1548
1549 /* free inode blocks before writing in line */
1550 if (Mcb->Inode.i_blocks) {
1551 LARGE_INTEGER Zero = {0, 0};
1552 Ext2TruncateFile(IrpContext, Vcb, Mcb, &Zero);
1553 }
1554
1555 ClearFlag(Mcb->Inode.i_flags, EXT4_EXTENTS_FL);
1558 }
1559
1560 Mcb->Inode.i_size = Size;
1561 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
1562
1563 if (BytesWritten) {
1564 *BytesWritten = Size;
1565 }
1566
1567out:
1568 return Status;
1569}
1570
1573{
1574 PIRP Irp = NULL;
1576
1578
1579 PEXT2_VCB Vcb = NULL;
1580 PEXT2_FCB Fcb = NULL;
1581 PEXT2_CCB Ccb = NULL;
1582 PEXT2_MCB Mcb = NULL;
1583
1585
1588 ULONG BytesWritten = 0;
1589
1590 PEXT2_FCB ParentDcb = NULL; /* Dcb of it's current parent */
1591 PEXT2_MCB ParentMcb = NULL;
1592
1594
1595 UNICODE_STRING UniName;
1597
1598 PCHAR OemNameBuffer = NULL;
1599 int OemNameLength = 0, i;
1600
1601 BOOLEAN MainResourceAcquired = FALSE;
1602 BOOLEAN FcbLockAcquired = FALSE;
1603
1604 _SEH2_TRY {
1605
1606 Ccb = IrpContext->Ccb;
1607 ASSERT(Ccb != NULL);
1609 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
1610 DeviceObject = IrpContext->DeviceObject;
1611 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
1612 Fcb = IrpContext->Fcb;
1613 Mcb = Fcb->Mcb;
1614 Irp = IrpContext->Irp;
1616
1618 FcbLockAcquired = TRUE;
1619
1620 ParentMcb = Mcb->Parent;
1621 ParentDcb = ParentMcb->Fcb;
1622 if (ParentDcb == NULL) {
1623 ParentDcb = Ext2AllocateFcb(Vcb, ParentMcb);
1624 }
1625 if (ParentDcb) {
1626 Ext2ReferXcb(&ParentDcb->ReferenceCount);
1627 }
1628
1629 if (!Mcb)
1631
1632 if (FcbLockAcquired) {
1633 ExReleaseResourceLite(&Vcb->FcbLock);
1634 FcbLockAcquired = FALSE;
1635 }
1636
1638 &Fcb->MainResource,
1639 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
1642 }
1643 MainResourceAcquired = TRUE;
1644
1645 InputBuffer = Irp->AssociatedIrp.SystemBuffer;
1647
1650 if (!NT_SUCCESS(Status)) {
1652 }
1653
1654 UniName.Length = RDB->SymbolicLinkReparseBuffer.SubstituteNameLength;
1655 UniName.MaximumLength = UniName.Length;
1656 UniName.Buffer =
1657 (PWCHAR)((PUCHAR)&RDB->SymbolicLinkReparseBuffer.PathBuffer
1658 + RDB->SymbolicLinkReparseBuffer.SubstituteNameOffset);
1659
1660 OemNameLength = Ext2UnicodeToOEMSize(Vcb, &UniName);
1661 if (OemNameLength > USHRT_MAX) {
1664 }
1665 OemName.Length = (USHORT)OemNameLength;
1666 OemName.MaximumLength = OemNameLength + 1;
1667 OemNameBuffer = OemName.Buffer = Ext2AllocatePool(PagedPool,
1668 OemName.MaximumLength,
1669 'NL2E');
1670 if (!OemNameBuffer) {
1673 }
1674
1675 Ext2UnicodeToOEM(Vcb, &OemName, &UniName);
1676 OemName.Buffer[OemName.Length] = '\0';
1677 for (i = 0;i < OemName.Length;i++) {
1678 if (OemName.Buffer[i] == '\\') {
1679 OemName.Buffer[i] = '/';
1680 }
1681 }
1682
1683 /* free all data blocks of the inode (to be set as symlink) */
1684 {
1685 LARGE_INTEGER zero = {0};
1686 Status = Ext2TruncateFile(IrpContext, Vcb, Mcb, &zero);
1687 }
1688
1689 /* decrease dir count of group desc and vcb stat */
1690 if (S_ISDIR(Mcb->Inode.i_mode)) {
1691
1692 ULONG group = (Mcb->Inode.i_ino - 1) / INODES_PER_GROUP;
1693 Ext2UpdateGroupDirStat(IrpContext, Vcb, group);
1694
1695 /* drop extra reference for dir inode */
1696 ext3_dec_count(&Mcb->Inode);
1697 }
1698
1699 /* overwrite inode mode as type SYMLINK */
1700 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
1702
1703 Status = Ext2WriteSymlink(IrpContext, Vcb, Mcb, OemNameBuffer,
1704 OemNameLength, &BytesWritten);
1705 if (NT_SUCCESS(Status)) {
1706 Ext2SetFileType(IrpContext, Vcb, ParentDcb, Mcb,
1707 S_IFLNK | S_IRWXUGO);
1708 }
1709
1710 } _SEH2_FINALLY {
1711
1712 if (FcbLockAcquired) {
1713 ExReleaseResourceLite(&Vcb->FcbLock);
1714 FcbLockAcquired = FALSE;
1715 }
1716
1717 if (MainResourceAcquired) {
1719 }
1720
1721 if (OemNameBuffer) {
1722 Ext2FreePool(OemNameBuffer, 'NL2E');
1723 }
1724
1725 if (NT_SUCCESS(Status)) {
1727 IrpContext,
1728 Vcb,
1729 Mcb,
1732 }
1733
1736 Status = Ext2QueueRequest(IrpContext);
1737 } else {
1738 Ext2CompleteIrpContext(IrpContext, Status);
1739 }
1740 }
1741
1742 if (ParentDcb) {
1744 }
1745 } _SEH2_END;
1746
1747 return Status;
1748}
1749
1752 PEXT2_IRP_CONTEXT IrpContext,
1753 PEXT2_VCB Vcb,
1754 PEXT2_MCB Mcb,
1755 ULONG Size
1756 )
1757{
1759 PUCHAR data = (PUCHAR)&Mcb->Inode.i_block;
1760 ULONG len = (ULONG)Mcb->Inode.i_size;
1762
1763 if (len < EXT2_LINKLEN_IN_INODE && !Mcb->Inode.i_blocks) {
1764
1766 Mcb->Inode.i_size = Size;
1767 Ext2SaveInode(IrpContext, Vcb, &Mcb->Inode);
1768
1769 } else {
1770 NewSize.QuadPart = Size;
1771 status = Ext2TruncateFile(IrpContext, Vcb, Mcb, &NewSize);
1772 if (!NT_SUCCESS(status)) {
1773 goto out;
1774 }
1775 }
1776
1777out:
1778 return status;
1779}
1780
1781
1782/* FIXME: We can only handle one reparse point right now. */
1785{
1786 PIRP Irp = NULL;
1787
1789
1790 PEXT2_VCB Vcb = NULL;
1791 PEXT2_FCB Fcb = NULL;
1792 PEXT2_CCB Ccb = NULL;
1793 PEXT2_MCB Mcb = NULL;
1794
1795 PEXT2_FCB ParentDcb = NULL; /* Dcb of it's current parent */
1796 PEXT2_MCB ParentMcb = NULL;
1797
1799
1800 BOOLEAN FcbLockAcquired = FALSE;
1801 BOOLEAN MainResourceAcquired = FALSE;
1802
1803
1804 _SEH2_TRY {
1805
1806 Ccb = IrpContext->Ccb;
1807 ASSERT(Ccb != NULL);
1809 (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
1810 DeviceObject = IrpContext->DeviceObject;
1811 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
1812 Mcb = IrpContext->Fcb->Mcb;
1813 Irp = IrpContext->Irp;
1814
1816 FcbLockAcquired = TRUE;
1817
1818 ParentMcb = Mcb->Parent;
1819 ParentDcb = ParentMcb->Fcb;
1820 if (ParentDcb == NULL) {
1821 ParentDcb = Ext2AllocateFcb(Vcb, ParentMcb);
1822 }
1823 if (ParentDcb) {
1824 Ext2ReferXcb(&ParentDcb->ReferenceCount);
1825 }
1826
1827 if (!Mcb || !IsInodeSymLink(&Mcb->Inode) ||
1831 }
1832
1834 if (Fcb) {
1835 Ext2ReferXcb(&Fcb->ReferenceCount);
1836 } else {
1839 }
1840
1841 if (FcbLockAcquired) {
1842 ExReleaseResourceLite(&Vcb->FcbLock);
1843 FcbLockAcquired = FALSE;
1844 }
1845
1847 &Fcb->MainResource,
1848 IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
1851 }
1852 MainResourceAcquired = TRUE;
1853
1854 Status = Ext2TruncateSymlink(IrpContext, Vcb, Mcb, 0);
1855 if (!NT_SUCCESS(Status)) {
1857 }
1858
1859 /* inode is to be removed */
1861
1862 } _SEH2_FINALLY {
1863
1864 if (FcbLockAcquired) {
1865 ExReleaseResourceLite(&Vcb->FcbLock);
1866 }
1867
1868 if (MainResourceAcquired) {
1870 }
1871
1872 if (NT_SUCCESS(Status)) {
1874 IrpContext,
1875 Vcb,
1876 Mcb,
1879
1880 }
1881
1884 Status = Ext2QueueRequest(IrpContext);
1885 } else {
1886 Ext2CompleteIrpContext(IrpContext, Status);
1887 }
1888 }
1889
1890 if (ParentDcb) {
1892 }
1893
1894 if (Fcb) {
1896 }
1897 } _SEH2_END;
1898
1899 return Status;
1900}
1901
1904{
1905 PIRP Irp;
1906 PIO_STACK_LOCATION IoStackLocation;
1909
1910 ASSERT(IrpContext);
1911
1912 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1913 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1914
1915 Irp = IrpContext->Irp;
1916 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
1917
1918#ifndef _GNU_NTIFS_
1920 IoStackLocation->Parameters.FileSystemControl.FsControlCode;
1921#else
1923 IoStackLocation)->Parameters.FileSystemControl.FsControlCode;
1924#endif
1925
1926 switch (FsControlCode) {
1927
1929 Status = Ext2GetReparsePoint(IrpContext);
1930 break;
1931
1933 Status = Ext2SetReparsePoint(IrpContext);
1934 break;
1935
1937 Status = Ext2DeleteReparsePoint(IrpContext);
1938 break;
1939
1940 case FSCTL_LOCK_VOLUME:
1941 Status = Ext2LockVolume(IrpContext);
1942 break;
1943
1945 Status = Ext2UnlockVolume(IrpContext);
1946 break;
1947
1949 Status = Ext2DismountVolume(IrpContext);
1950 break;
1951
1953 Status = Ext2IsVolumeMounted(IrpContext);
1954 break;
1955
1957 Status = Ext2InvalidateVolumes(IrpContext);
1958 break;
1959
1960#if (_WIN32_WINNT >= 0x0500)
1962 Status = Ext2AllowExtendedDasdIo(IrpContext);
1963 break;
1964#endif //(_WIN32_WINNT >= 0x0500)
1965
1973
1974 Status = Ext2OplockRequest(IrpContext);
1975 break;
1976
1978 Status = Ext2IsVolumeDirty(IrpContext);
1979 break;
1980
1982 Status = Ext2QueryRetrievalPointers(IrpContext);
1983 break;
1984
1986 Status = Ext2GetRetrievalPointers(IrpContext);
1987 break;
1988
1990 Status = Ext2GetRetrievalPointerBase(IrpContext);
1991 break;
1992
1993 default:
1994
1995 DEBUG(DL_INF, ( "Ext2UserFsRequest: Invalid User Request: %xh.\n", FsControlCode));
1997
1998 Ext2CompleteIrpContext(IrpContext, Status);
1999 }
2000
2001 return Status;
2002}
2003
2004BOOLEAN
2006 IN PEXT2_IRP_CONTEXT IrpContext,
2008)
2009{
2010 PIRP Irp;
2011 KEVENT Event;
2014
2016
2019 NULL,
2020 0,
2021 NULL,
2022 0,
2023 FALSE,
2024 &Event,
2025 &IoStatus );
2026
2027 if (Irp == NULL) {
2028 return FALSE;
2029 }
2030
2032
2034
2035 if (Status == STATUS_PENDING) {
2036
2038 Executive,
2039 KernelMode,
2040 FALSE,
2042
2043 Status = IoStatus.Status;
2044 }
2045
2047}
2048
2051{
2053 BOOLEAN GlobalDataResourceAcquired = FALSE;
2054 PIRP Irp;
2055 PIO_STACK_LOCATION IoStackLocation;
2058 PDEVICE_OBJECT VolumeDeviceObject = NULL;
2059 PEXT2_VCB Vcb = NULL, OldVcb = NULL;
2060 PVPB OldVpb = NULL, Vpb = NULL;
2061 PEXT2_SUPER_BLOCK Ext2Sb = NULL;
2062 ULONG dwBytes;
2063 DISK_GEOMETRY DiskGeometry;
2064
2065 _SEH2_TRY {
2066
2067 ASSERT(IrpContext != NULL);
2068 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2069 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2070
2071 MainDeviceObject = IrpContext->DeviceObject;
2072
2073 //
2074 // Make sure we can wait.
2075 //
2076
2077 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
2078
2079 //
2080 // This request is only allowed on the main device object
2081 //
2085 }
2086
2090 }
2091
2092#if 0
2093 if (IrpContext->RealDevice->Size >= sizeof(ULONG) + sizeof(DEVICE_OBJECT) &&
2094 *((PULONG)IrpContext->RealDevice->DeviceExtension) == 'DSSA') {
2095 } else {
2098 }
2099#endif
2100
2101 Irp = IrpContext->Irp;
2102 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
2104 IoStackLocation->Parameters.MountVolume.DeviceObject;
2105
2106 dwBytes = sizeof(DISK_GEOMETRY);
2110 NULL,
2111 0,
2112 &DiskGeometry,
2113 &dwBytes );
2114
2115 if (!NT_SUCCESS(Status)) {
2117 }
2118
2120 MainDeviceObject->DriverObject,
2121 sizeof(EXT2_VCB),
2122 NULL,
2124 0,
2125 FALSE,
2126 &VolumeDeviceObject );
2127
2128 if (!NT_SUCCESS(Status)) {
2130 }
2131 INC_MEM_COUNT(PS_VCB, VolumeDeviceObject, sizeof(EXT2_VCB));
2132
2133#ifdef _PNP_POWER_
2134 /* don't care about power management requests */
2135 VolumeDeviceObject->DeviceObjectExtension->PowerControlNeeded = FALSE;
2136#endif
2137
2138 VolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1);
2139 ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
2140
2141/*
2142 These are for buffer-address alignment requirements.
2143 Never do this check, unless you want fail user requests :)
2144
2145 if (TargetDeviceObject->AlignmentRequirement >
2146 VolumeDeviceObject->AlignmentRequirement) {
2147
2148 VolumeDeviceObject->AlignmentRequirement =
2149 TargetDeviceObject->AlignmentRequirement;
2150 }
2151
2152 if (DiskGeometry.BytesPerSector - 1 >
2153 VolumeDeviceObject->AlignmentRequirement) {
2154 VolumeDeviceObject->AlignmentRequirement =
2155 DiskGeometry.BytesPerSector - 1;
2156 TargetDeviceObject->AlignmentRequirement =
2157 DiskGeometry.BytesPerSector - 1;
2158 }
2159*/
2160 (IoStackLocation->Parameters.MountVolume.Vpb)->DeviceObject =
2161 VolumeDeviceObject;
2162 Vpb = IoStackLocation->Parameters.MountVolume.Vpb;
2163
2164 Vcb = (PEXT2_VCB) VolumeDeviceObject->DeviceExtension;
2165
2166 RtlZeroMemory(Vcb, sizeof(EXT2_VCB));
2167 Vcb->Identifier.Type = EXT2VCB;
2168 Vcb->Identifier.Size = sizeof(EXT2_VCB);
2169 Vcb->TargetDeviceObject = TargetDeviceObject;
2170 Vcb->DiskGeometry = DiskGeometry;
2171 InitializeListHead(&Vcb->Next);
2172
2173 Status = Ext2LoadSuper(Vcb, FALSE, &Ext2Sb);
2174 if (!NT_SUCCESS(Status)) {
2175 Vcb = NULL;
2178 }
2179 ASSERT (NULL != Ext2Sb);
2180
2181 /* check Linux Ext2/Ext3 volume magic */
2182 if (Ext2Sb->s_magic == EXT2_SUPER_MAGIC) {
2183 DEBUG(DL_INF, ( "Volume of ext2 file system is found.\n"));
2184 } else {
2186 Vcb = NULL;
2188 }
2189
2190 DEBUG(DL_DBG, ("Ext2MountVolume: DevObject=%p Vcb=%p\n", VolumeDeviceObject, Vcb));
2191
2192 /* initialize Vcb structure */
2193 Status = Ext2InitializeVcb( IrpContext, Vcb, Ext2Sb,
2195 VolumeDeviceObject, Vpb);
2196
2197 if (NT_SUCCESS(Status)) {
2198
2200
2202 GlobalDataResourceAcquired = TRUE;
2203
2204 for (List = Ext2Global->VcbList.Flink;
2205 List != &Ext2Global->VcbList;
2206 List = List->Flink) {
2207
2208 OldVcb = CONTAINING_RECORD(List, EXT2_VCB, Next);
2209 OldVpb = OldVcb->Vpb;
2210
2211 /* in case we are already in the queue, should not happen */
2212 if (OldVpb == Vpb) {
2213 continue;
2214 }
2215
2216 if ( (OldVpb->SerialNumber == Vpb->SerialNumber) &&
2217 (!IsMounted(OldVcb)) && (IsFlagOn(OldVcb->Flags, VCB_NEW_VPB)) &&
2218 (OldVpb->RealDevice == TargetDeviceObject) &&
2219 (OldVpb->VolumeLabelLength == Vpb->VolumeLabelLength) &&
2220 (RtlEqualMemory(&OldVpb->VolumeLabel[0],
2221 &Vpb->VolumeLabel[0],
2222 Vpb->VolumeLabelLength)) &&
2223 (RtlEqualMemory(&OldVcb->SuperBlock->s_uuid[0],
2224 &Vcb->SuperBlock->s_uuid[0], 16)) ) {
2225 ClearFlag(OldVcb->Flags, VCB_MOUNTED);
2226 }
2227 }
2228
2229 SetLongFlag(Vcb->Flags, VCB_MOUNTED);
2230 SetFlag(Vcb->Vpb->Flags, VPB_MOUNTED);
2232 Vcb = NULL;
2233 Vpb = NULL;
2235
2236 } else {
2237
2238 Vcb = NULL;
2239 }
2240
2241 } _SEH2_FINALLY {
2242
2243 if (GlobalDataResourceAcquired) {
2245 }
2246
2247 if (!NT_SUCCESS(Status)) {
2248
2249 if (!NT_SUCCESS(Status)) {
2250 if ( Vpb != NULL ) {
2251 Vpb->DeviceObject = NULL;
2252 }
2253 }
2254
2255 if (Vcb) {
2257 } else {
2258 if (Ext2Sb) {
2259 Ext2FreePool(Ext2Sb, EXT2_SB_MAGIC);
2260 }
2261 if (VolumeDeviceObject) {
2262 IoDeleteDevice(VolumeDeviceObject);
2263 DEC_MEM_COUNT(PS_VCB, VolumeDeviceObject, sizeof(EXT2_VCB));
2264 }
2265 }
2266 }
2267
2268 if (!IrpContext->ExceptionInProgress) {
2269 Ext2CompleteIrpContext(IrpContext, Status);
2270 }
2271 } _SEH2_END;
2272
2273 return Status;
2274}
2275
2276VOID
2278 IN PEXT2_VCB Vcb )
2279{
2281
2283 ULONG ChangeCount = 0;
2284 ULONG dwBytes;
2285
2286 PIRP Irp;
2288
2289 _SEH2_TRY {
2290
2291 ASSERT(IrpContext != NULL);
2292
2293 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2294 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2295
2296 Irp = IrpContext->Irp;
2298
2299 bVerify = IsFlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
2300
2301 if ( (IsFlagOn(Vcb->Flags, VCB_REMOVABLE_MEDIA) ||
2302 IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) && !bVerify ) {
2303
2304 dwBytes = sizeof(ULONG);
2306 Vcb->TargetDeviceObject,
2308 NULL,
2309 0,
2310 &ChangeCount,
2311 &dwBytes );
2312
2316 (NT_SUCCESS(Status) &&
2317 (ChangeCount != Vcb->ChangeCount))) {
2318
2319 KIRQL Irql;
2320
2322 if (Vcb->Vpb == Vcb->Vpb->RealDevice->Vpb) {
2323 SetFlag(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
2324 }
2326
2327 } else {
2328
2329 if (!NT_SUCCESS(Status)) {
2331 }
2332 }
2333 }
2334
2335 if ( IsFlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME)) {
2336 IoSetHardErrorOrVerifyDevice( Irp, Vcb->Vpb->RealDevice );
2337 Ext2NormalizeAndRaiseStatus ( IrpContext,
2339 }
2340
2341 if (IsMounted(Vcb)) {
2342
2343 if ( (IrpContext->MajorFunction == IRP_MJ_WRITE) ||
2344 (IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) ||
2345 (IrpContext->MajorFunction == IRP_MJ_SET_EA) ||
2346 (IrpContext->MajorFunction == IRP_MJ_FLUSH_BUFFERS) ||
2347 (IrpContext->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION) ||
2348 (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
2349 IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST &&
2350 IrpSp->Parameters.FileSystemControl.FsControlCode ==
2352
2353 if (IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
2354
2355 KIRQL Irql;
2356
2358 if (Vcb->Vpb == Vcb->Vpb->RealDevice->Vpb) {
2359 SetFlag (Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
2360 }
2362
2363 IoSetHardErrorOrVerifyDevice( Irp, Vcb->Vpb->RealDevice );
2364
2366 }
2367 }
2368 }
2369
2370 } _SEH2_FINALLY {
2371
2372 } _SEH2_END;
2373
2374}
2375
2376
2379{
2382 PEXT2_SUPER_BLOCK ext2_sb = NULL;
2383 PEXT2_VCB Vcb = NULL;
2384 BOOLEAN VcbResourceAcquired = FALSE;
2385 PIRP Irp;
2386 ULONG ChangeCount = 0;
2387 ULONG dwBytes;
2388
2389 _SEH2_TRY {
2390
2391 ASSERT(IrpContext != NULL);
2392 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2393 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2394
2395 DeviceObject = IrpContext->DeviceObject;
2396 //
2397 // This request is not allowed on the main device object
2398 //
2402 }
2403
2404 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
2405 ASSERT(Vcb != NULL);
2406 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
2407 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
2408
2409 VcbResourceAcquired =
2411 &Vcb->MainResource,
2412 TRUE );
2413
2414 if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME)) {
2417 }
2418
2419 if (!IsMounted(Vcb)) {
2422 }
2423
2424 dwBytes = sizeof(ULONG);
2426 Vcb->TargetDeviceObject,
2428 NULL,
2429 0,
2430 &ChangeCount,
2431 &dwBytes );
2432
2433
2434 if (!NT_SUCCESS(Status)) {
2437 } else {
2438 Vcb->ChangeCount = ChangeCount;
2439 }
2440
2441 Irp = IrpContext->Irp;
2442
2443 Status = Ext2LoadSuper(Vcb, TRUE, &ext2_sb);
2444
2445 if (!NT_SUCCESS(Status)) {
2447 }
2448
2449 ASSERT(NULL != ext2_sb);
2450 if ((ext2_sb->s_magic == EXT2_SUPER_MAGIC) &&
2451 (memcmp(ext2_sb->s_uuid, SUPER_BLOCK->s_uuid, 16) == 0) &&
2452 (memcmp(ext2_sb->s_volume_name, SUPER_BLOCK->s_volume_name, 16) ==0)) {
2453
2454 ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
2455
2456 if (Ext2IsMediaWriteProtected(IrpContext, Vcb->TargetDeviceObject)) {
2458 } else {
2460 }
2461
2462 DEBUG(DL_INF, ( "Ext2VerifyVolume: Volume verify succeeded.\n"));
2463
2464 } else {
2465
2468
2470 ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
2471
2472 DEBUG(DL_INF, ( "Ext2VerifyVolume: Volume verify failed.\n"));
2473 }
2474
2475 } _SEH2_FINALLY {
2476
2477 if (ext2_sb)
2478 Ext2FreePool(ext2_sb, EXT2_SB_MAGIC);
2479
2480 if (VcbResourceAcquired) {
2481 ExReleaseResourceLite(&Vcb->MainResource);
2482 }
2483
2484 if (!IrpContext->ExceptionInProgress) {
2485 Ext2CompleteIrpContext(IrpContext, Status);
2486 }
2487 } _SEH2_END;
2488
2489 return Status;
2490}
2491
2492
2495{
2497 PEXT2_VCB Vcb = 0;
2499
2500 ASSERT(IrpContext);
2501
2502 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2503 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2504
2505
2506 DeviceObject = IrpContext->DeviceObject;
2507
2508 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
2509
2511
2512 Ext2VerifyVcb (IrpContext, Vcb);
2513
2514 Ext2CompleteIrpContext(IrpContext, Status);
2515
2516 return Status;
2517}
2518
2519
2522{
2525 PEXT2_VCB Vcb = NULL;
2526 BOOLEAN VcbResourceAcquired = FALSE;
2527
2528 _SEH2_TRY {
2529
2530 ASSERT(IrpContext != NULL);
2531
2532 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2533 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2534
2535 DeviceObject = IrpContext->DeviceObject;
2536
2537 //
2538 // This request is not allowed on the main device object
2539 //
2543 }
2544
2545 Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
2546
2547 ASSERT(Vcb != NULL);
2548
2549 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
2550 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
2551
2553
2555 &Vcb->MainResource,
2556 TRUE );
2557
2558 VcbResourceAcquired = TRUE;
2559
2560 if ( IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
2563 }
2564
2565 Ext2FlushFiles(IrpContext, Vcb, FALSE);
2566 Ext2FlushVolume(IrpContext, Vcb, FALSE);
2567
2568 ExReleaseResourceLite(&Vcb->MainResource);
2569 VcbResourceAcquired = FALSE;
2570
2572 Ext2CheckDismount(IrpContext, Vcb, TRUE);
2573
2574 DEBUG(DL_INF, ( "Ext2Dismount: Volume dismount pending.\n"));
2576
2577 } _SEH2_FINALLY {
2578
2579 if (VcbResourceAcquired) {
2580 ExReleaseResourceLite(&Vcb->MainResource);
2581 }
2582
2583 if (!IrpContext->ExceptionInProgress) {
2584 Ext2CompleteIrpContext(IrpContext, Status);
2585 }
2586 } _SEH2_END;
2587
2588 return Status;
2589}
2590
2591BOOLEAN
2593 IN PEXT2_IRP_CONTEXT IrpContext,
2595 IN BOOLEAN bForce )
2596{
2597 KIRQL Irql;
2598 PVPB Vpb = Vcb->Vpb, NewVpb = NULL;
2599 BOOLEAN bDeleted = FALSE, bTearDown = FALSE;
2600 ULONG UnCleanCount = 0;
2601
2603 if (NewVpb == NULL) {
2604 DEBUG(DL_ERR, ( "Ex2CheckDismount: failed to allocate NewVpb.\n"));
2605 return FALSE;
2606 }
2607 DEBUG(DL_DBG, ("Ext2CheckDismount: NewVpb allocated: %p\n", NewVpb));
2608 INC_MEM_COUNT(PS_VPB, NewVpb, sizeof(VPB));
2609 memset(NewVpb, '_', VPB_SIZE);
2610 RtlZeroMemory(NewVpb, sizeof(VPB));
2611
2614
2616 &Vcb->MainResource, TRUE );
2617
2618 if (IrpContext &&
2619 IrpContext->MajorFunction == IRP_MJ_CREATE &&
2620 IrpContext->RealDevice == Vcb->RealDevice) {
2621 UnCleanCount = 2;
2622 } else {
2623 UnCleanCount = 1;
2624 }
2625
2627
2628 DEBUG(DL_DBG, ("Ext2CheckDismount: Vpb %p ioctl=%d Device %p\n",
2629 Vpb, Vpb->ReferenceCount, Vpb->RealDevice));
2630
2631 if (Vpb->ReferenceCount <= UnCleanCount) {
2632
2633 if (!IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
2634
2635 ClearFlag(Vpb->Flags, VPB_MOUNTED);
2636 ClearFlag(Vpb->Flags, VPB_LOCKED);
2637
2638 if ((Vcb->RealDevice != Vpb->RealDevice) &&
2639 (Vcb->RealDevice->Vpb == Vpb)) {
2640 SetFlag(Vcb->RealDevice->Flags, DO_DEVICE_INITIALIZING);
2641 SetFlag(Vpb->Flags, VPB_PERSISTENT );
2642 }
2643
2646 }
2647
2648 if (Vpb->ReferenceCount) {
2649 bTearDown = TRUE;
2650 } else {
2651 bDeleted = TRUE;
2652 Vpb->DeviceObject = NULL;
2653 }
2654
2655 DEBUG(DL_DBG, ("Ext2CheckDismount: Vpb: %p bDeleted=%d bTearDown=%d\n",
2656 Vpb, bDeleted, bTearDown));
2657
2658
2659 } else if (bForce) {
2660
2661 DEBUG(DL_DBG, ( "Ext2CheckDismount: New/Old Vpb %p/%p Realdevice = %p\n",
2662 NewVpb, Vcb->Vpb, Vpb->RealDevice));
2663
2664 /* keep vpb president and later we'll free it */
2665 SetFlag(Vpb->Flags, VPB_PERSISTENT);
2666
2667 Vcb->Vpb2 = Vcb->Vpb;
2668 NewVpb->Type = IO_TYPE_VPB;
2669 NewVpb->Size = sizeof(VPB);
2670 NewVpb->Flags = Vpb->Flags & VPB_REMOVE_PENDING;
2671 NewVpb->RealDevice = Vpb->RealDevice;
2672 NewVpb->RealDevice->Vpb = NewVpb;
2673 NewVpb = NULL;
2674 ClearFlag(Vpb->Flags, VPB_MOUNTED);
2675 SetLongFlag(Vcb->Flags, VCB_NEW_VPB);
2676 ClearLongFlag(Vcb->Flags, VCB_MOUNTED);
2677 }
2678
2680
2681 ExReleaseResourceLite(&Vcb->MainResource);
2683
2684 if (bTearDown) {
2685 DEBUG(DL_DBG, ( "Ext2CheckDismount: Tearing vcb %p ...\n", Vcb));
2687 }
2688
2689 if (bDeleted) {
2690 DEBUG(DL_DBG, ( "Ext2CheckDismount: Deleting vcb %p ...\n", Vcb));
2692 }
2693
2694 if (NewVpb != NULL) {
2695 DEBUG(DL_DBG, ( "Ext2CheckDismount: freeing new Vpb %p\n", NewVpb));
2696 ExFreePoolWithTag(NewVpb, TAG_VPB);
2697 DEC_MEM_COUNT(PS_VPB, NewVpb, sizeof(VPB));
2698 }
2699
2700 return bDeleted;
2701}
2702
2705 IN BOOLEAN FlushBeforePurge )
2706{
2707 PEXT2_FCB Fcb;
2708 LIST_ENTRY List, *Next;
2709
2710 BOOLEAN VcbResourceAcquired = FALSE;
2711 BOOLEAN FcbResourceAcquired = FALSE;
2712 BOOLEAN gdResourceAcquired = FALSE;
2713
2714 _SEH2_TRY {
2715
2716 ASSERT(Vcb != NULL);
2717 ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
2718 (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
2719
2720 ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE);
2721 VcbResourceAcquired = TRUE;
2722
2723 if (IsVcbReadOnly(Vcb)) {
2724 FlushBeforePurge = FALSE;
2725 }
2726
2728
2730 FcbResourceAcquired = TRUE;
2731
2732 while (!IsListEmpty(&Vcb->FcbList)) {
2733
2734 Next = RemoveHeadList(&Vcb->FcbList);
2735 Fcb = CONTAINING_RECORD(Next, EXT2_FCB, Next);
2736
2737 DEBUG(DL_INF, ( "Ext2PurgeVolume: %wZ refercount=%xh\n",
2738 &Fcb->Mcb->FullName, Fcb->ReferenceCount));
2739 InsertTailList(&List, &Fcb->Next);
2740 }
2741
2742 while (!IsListEmpty(&List)) {
2743
2744 Next = RemoveHeadList(&List);
2745 Fcb = CONTAINING_RECORD(Next, EXT2_FCB, Next);
2746
2748 &Fcb->MainResource,
2749 TRUE )) {
2750
2751 Ext2PurgeFile(Fcb, FlushBeforePurge);
2752
2753 if (Fcb->ReferenceCount <= 1) {
2754 Fcb->TsDrop.QuadPart = 0;
2755 InsertHeadList(&Vcb->FcbList, &Fcb->Next);
2756 } else {
2757 InsertTailList(&Vcb->FcbList, &Fcb->Next);
2758 }
2760 }
2761 }
2762
2763 if (FcbResourceAcquired) {
2764 ExReleaseResourceLite(&Vcb->FcbLock);
2765 FcbResourceAcquired = FALSE;
2766 }
2767
2768 /* acquire bd lock to avoid bh creation */
2769 ExAcquireResourceExclusiveLite(&Vcb->sbi.s_gd_lock, TRUE);
2770 gdResourceAcquired = TRUE;
2771
2772 /* discard buffer_headers for group_desc */
2773 Ext2DropBH(Vcb);
2774
2775 if (FlushBeforePurge) {
2776 ExAcquireSharedStarveExclusive(&Vcb->PagingIoResource, TRUE);
2777 ExReleaseResourceLite(&Vcb->PagingIoResource);
2778
2779 CcFlushCache(&Vcb->SectionObject, NULL, 0, NULL);
2780 }
2781
2782 if (Vcb->SectionObject.ImageSectionObject) {
2783 MmFlushImageSection(&Vcb->SectionObject, MmFlushForWrite);
2784 }
2785
2786 if (Vcb->SectionObject.DataSectionObject) {
2787 CcPurgeCacheSection(&Vcb->SectionObject, NULL, 0, FALSE);
2788 }
2789
2790 DEBUG(DL_INF, ( "Ext2PurgeVolume: Volume flushed and purged.\n"));
2791
2792 } _SEH2_FINALLY {
2793
2794 if (gdResourceAcquired) {
2795 ExReleaseResourceLite(&Vcb->sbi.s_gd_lock);
2796 }
2797
2798 if (FcbResourceAcquired) {
2799 ExReleaseResourceLite(&Vcb->FcbLock);
2800 }
2801
2802 if (VcbResourceAcquired) {
2803 ExReleaseResourceLite(&Vcb->MainResource);
2804 }
2805 } _SEH2_END;
2806
2807 return STATUS_SUCCESS;
2808}
2809
2812 IN BOOLEAN FlushBeforePurge )
2813{
2815
2816 ASSERT(Fcb != NULL);
2817
2819 (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
2820
2821
2822 if (!IsVcbReadOnly(Fcb->Vcb) && FlushBeforePurge) {
2823 DEBUG(DL_INF, ( "Ext2PurgeFile: CcFlushCache on %wZ.\n",
2824 &Fcb->Mcb->FullName));
2827 CcFlushCache(&Fcb->SectionObject, NULL, 0, &IoStatus);
2829 }
2830
2831 if (Fcb->SectionObject.ImageSectionObject) {
2832 DEBUG(DL_INF, ( "Ext2PurgeFile: MmFlushImageSection on %wZ.\n",
2833 &Fcb->Mcb->FullName));
2834 MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
2835 }
2836
2837 if (Fcb->SectionObject.DataSectionObject) {
2838 DEBUG(DL_INF, ( "Ext2PurgeFile: CcPurgeCacheSection on %wZ.\n",
2839 &Fcb->Mcb->FullName));
2840 CcPurgeCacheSection(&Fcb->SectionObject, NULL, 0, FALSE);
2841 }
2842
2843 return STATUS_SUCCESS;
2844}
2845
2846
2849{
2851
2852 ASSERT(IrpContext);
2853
2854 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
2855 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
2856
2857 switch (IrpContext->MinorFunction) {
2858
2860 Status = Ext2UserFsRequest(IrpContext);
2861 break;
2862
2864 Status = Ext2MountVolume(IrpContext);
2865 break;
2866
2868 Status = Ext2VerifyVolume(IrpContext);
2869 break;
2870
2871 default:
2872
2873 DEBUG(DL_ERR, ( "Ext2FilsSystemControl: Invalid Device Request.\n"));
2875 Ext2CompleteIrpContext(IrpContext, Status);
2876 }
2877
2878 return Status;
2879}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
static PDEVICE_OBJECT MainDeviceObject
unsigned char BOOLEAN
unsigned int UINT32
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define VOID
Definition: acefi.h:82
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
#define S_ISDIR(mode)
Definition: various.h:18
#define LongToHandle(h)
Definition: basetsd.h:82
unsigned int * PUINT32
Definition: basetsd.h:125
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 TAG_VPB
Definition: cdprocs.h:106
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
Definition: bufpool.h:45
Definition: Header.h:9
_In_ PIRP Irp
Definition: csq.h:116
_Out_ PKIRQL Irql
Definition: csq.h:179
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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:33
#define BLOCK_BITS
Definition: stream.h:22
#define PS_VPB
Definition: common.h:23
#define PS_VCB
Definition: common.h:17
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB ParentDcb
Definition: create.c:4141
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define PagedPool
Definition: env_spec_w32.h:308
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
NTSTATUS Ext2UnlockVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:241
BOOLEAN Ext2IsHandleCountZero(IN PEXT2_VCB Vcb)
Definition: fsctl.c:68
NTSTATUS Ext2QueryRetrievalPointers(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:774
NTSTATUS Ext2InspectReparseData(IN PREPARSE_DATA_BUFFER RDB, IN ULONG InputBufferLength)
Definition: fsctl.c:1293
NTSTATUS Ext2UnlockVcb(IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject)
Definition: fsctl.c:206
NTSTATUS Ext2OplockRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:451
NTSTATUS Ext2QueryExtentMappings(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Fcb, IN PLARGE_INTEGER RequestVbn, OUT PLARGE_INTEGER *pMappedRuns)
Definition: fsctl.c:670
NTSTATUS Ext2PurgeVolume(IN PEXT2_VCB Vcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:2704
BOOLEAN Ext2IsMediaWriteProtected(IN PEXT2_IRP_CONTEXT IrpContext, IN PDEVICE_OBJECT TargetDevice)
Definition: fsctl.c:2005
NTSTATUS Ext2VerifyVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2378
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2DeleteReparsePoint(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1784
NTSTATUS Ext2TruncateSymlink(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, ULONG Size)
Definition: fsctl.c:1751
BOOLEAN Ext2CheckDismount(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bForce)
Definition: fsctl.c:2592
NTSTATUS Ext2AllowExtendedDasdIo(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:407
NTSTATUS Ext2GetRetrievalPointers(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:911
NTSTATUS Ext2WriteSymlink(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN PVOID Buffer, IN ULONG Size, OUT PULONG BytesWritten)
Definition: fsctl.c:1519
VOID Ext2ClearVpbFlag(IN PVPB Vpb, IN USHORT Flag)
Definition: fsctl.c:56
NTSTATUS Ext2ReadSymlink(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN PVOID Buffer, IN ULONG Size, OUT PULONG BytesRead)
Definition: fsctl.c:1364
NTSTATUS Ext2LockVcb(IN PEXT2_VCB Vcb, IN PFILE_OBJECT FileObject)
Definition: fsctl.c:94
NTSTATUS Ext2DismountVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2521
VOID Ext2VerifyVcb(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb)
Definition: fsctl.c:2277
NTSTATUS Ext2FileSystemControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2848
NTSTATUS Ext2GetRetrievalPointerBase(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1160
NTSTATUS Ext2GetReparsePoint(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1386
NTSTATUS Ext2UserFsRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1903
VOID Ext2SetVpbFlag(IN PVPB Vpb, IN USHORT Flag)
Definition: fsctl.c:44
NTSTATUS Ext2InvalidateVolumes(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:296
NTSTATUS Ext2IsVolumeMounted(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2494
NTSTATUS Ext2MountVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2050
NTSTATUS Ext2LockVolume(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:136
VOID Ext2InitializeReparseData(IN PREPARSE_DATA_BUFFER RDB, USHORT PathBufferLength)
Definition: fsctl.c:1346
NTSTATUS Ext2PurgeFile(IN PEXT2_FCB Fcb, IN BOOLEAN FlushBeforePurge)
Definition: fsctl.c:2811
NTSTATUS Ext2IsVolumeDirty(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:618
NTSTATUS Ext2SetReparsePoint(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:1572
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:910
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:789
#define VCB_WRITE_PROTECTED
Definition: ext2fs.h:805
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
VOID Ext2JointExtents(IN PEXT2_EXTENT Chain, IN PEXT2_EXTENT Extent)
Definition: memory.c:527
VOID Ext2RemoveVcb(PEXT2_VCB Vcb)
Definition: memory.c:1943
VOID Ext2ReleaseFcb(IN PEXT2_FCB Fcb)
Definition: memory.c:276
#define Ext2RaiseStatus(IRPCONTEXT, STATUS)
Definition: ext2fs.h:263
#define VCB_REMOVABLE_MEDIA
Definition: ext2fs.h:808
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
@ EXT2FCB
Definition: ext2fs.h:463
@ EXT2ICX
Definition: ext2fs.h:465
@ EXT2VCB
Definition: ext2fs.h:462
@ EXT2CCB
Definition: ext2fs.h:464
#define S_IRWXUGO
Definition: ext2fs.h:400
#define IsVcbReadOnly(Vcb)
Definition: ext2fs.h:814
#define IsMounted(Vcb)
Definition: ext2fs.h:812
NTSTATUS Ext2TruncateFile(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb, PLARGE_INTEGER AllocationSize)
Definition: fileinfo.c:1204
VOID Ext2DestroyExtentChain(IN PEXT2_EXTENT Chain)
Definition: memory.c:546
#define VPB_SIZE
Definition: ext2fs.h:294
struct _EXT2_VCB EXT2_VCB
VOID Ext2TearDownStream(IN PEXT2_VCB Vcb)
Definition: memory.c:2798
BOOLEAN Ext2SaveInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:552
#define EXT2_LINKLEN_IN_INODE
Definition: ext2fs.h:76
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:616
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:158
#define Ext2ReferXcb(_C)
Definition: ext2fs.h:976
#define EXT2_SUPER_MAGIC
Definition: ext2fs.h:349
#define CCB_OPEN_REPARSE_POINT
Definition: ext2fs.h:1034
#define DEC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:608
#define SetLongFlag(_F, _SF)
Definition: ext2fs.h:258
#define DL_INF
Definition: ext2fs.h:1436
#define FCB_PAGE_FILE
Definition: ext2fs.h:881
NTSTATUS Ext2OEMToUnicode(IN PEXT2_VCB Vcb, IN OUT PUNICODE_STRING Oem, IN POEM_STRING Unicode)
Definition: misc.c:206
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:791
#define INODES_PER_GROUP
Definition: ext2fs.h:99
#define Ext2NormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: ext2fs.h:268
NTSTATUS Ext2BuildExtents(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN ULONG Size, IN BOOLEAN bAlloc, OUT PEXT2_EXTENT *Chain)
Definition: memory.c:1207
#define FCB_FILE_MODIFIED
Definition: ext2fs.h:882
#define VCB_NEW_VPB
Definition: ext2fs.h:792
ULONG Ext2UnicodeToOEMSize(IN PEXT2_VCB Vcb, IN PUNICODE_STRING Unicode)
Definition: misc.c:239
#define EXT2_SB_MAGIC
Definition: ext2fs.h:302
#define SUPER_BLOCK
Definition: ext2fs.h:90
#define ClearLongFlag(_F, _SF)
Definition: ext2fs.h:259
#define Ext2BugCheck(A, B, C, D)
Definition: ext2fs.h:340
#define DL_MAP
Definition: ext2fs.h:1444
void ext3_dec_count(struct inode *inode)
Definition: htree.c:312
VOID Ext2DestroyVcb(IN PEXT2_VCB Vcb)
Definition: memory.c:2825
NTSTATUS Ext2InitializeVcb(PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_SUPER_BLOCK Ext2Sb, PDEVICE_OBJECT TargetDevice, PDEVICE_OBJECT VolumeDevice, PVPB Vpb)
PVOID Ext2GetUserBuffer(IN PIRP Irp)
Definition: block.c:146
VOID Ext2NotifyReportChange(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Filter, IN ULONG Action)
Definition: dirctl.c:1209
#define IsInodeSymLink(I)
Definition: ext2fs.h:286
#define Ext2CanIWait()
Definition: ext2fs.h:1100
#define DbgBreak()
Definition: ext2fs.h:46
#define VCB_MOUNTED
Definition: ext2fs.h:790
NTSTATUS Ext2SetFileType(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN PEXT2_MCB Mcb, IN umode_t mode)
Definition: generic.c:1951
#define EXT2_UNLOAD_PENDING
Definition: ext2fs.h:590
struct _EXT2_VCB * PEXT2_VCB
ULONG Ext2CountExtents(IN PEXT2_EXTENT Chain)
Definition: memory.c:513
NTSTATUS Ext2UnicodeToOEM(IN PEXT2_VCB Vcb, IN OUT POEM_STRING Oem, IN PUNICODE_STRING Unicode)
Definition: misc.c:261
#define FSCTL_GET_RETRIEVAL_POINTER_BASE
Definition: ext2fs.h:1132
#define CCB_DELETE_ON_CLOSE
Definition: ext2fs.h:1035
NTSTATUS Ext2UpdateGroupDirStat(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Group)
Definition: generic.c:1728
NTSTATUS Ext2LoadSuper(IN PEXT2_VCB Vcb, IN BOOLEAN bVerify, OUT PEXT2_SUPER_BLOCK *Sb)
Definition: generic.c:29
struct _EXT2_CCB * PEXT2_CCB
#define DL_ERR
Definition: ext2fs.h:1434
struct _EXT2_FCB * PEXT2_FCB
VOID Ext2DropBH(IN PEXT2_VCB Vcb)
Definition: generic.c:266
ULONG Ext2OEMToUnicodeSize(IN PEXT2_VCB Vcb, IN PANSI_STRING Oem)
Definition: misc.c:183
VOID Ext2InsertVcb(PEXT2_VCB Vcb)
Definition: memory.c:1935
NTSTATUS Ext2DiskIoControl(IN PDEVICE_OBJECT DeviceOjbect, IN ULONG IoctlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG OutputBufferSize)
Definition: block.c:609
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define MCB_FILE_DELETED
Definition: ext2fs.h:955
#define CCB_ALLOW_EXTENDED_DASD_IO
Definition: ext2fs.h:1037
NTSTATUS Ext2FlushFiles(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:112
#define INC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:607
#define DL_DBG
Definition: ext2fs.h:1435
#define VCB_FLOPPY_DISK
Definition: ext2fs.h:806
PEXT2_FCB Ext2AllocateFcb(IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb)
Definition: memory.c:131
NTSTATUS Ext2WriteInode(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONGLONG Offset, IN PVOID Buffer, IN ULONG Size, IN BOOLEAN bDirectIo, OUT PULONG dwReturn)
Definition: write.c:668
NTSTATUS Ext2FlushVolume(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN BOOLEAN bShutDown)
Definition: flush.c:43
#define EXT2_BUGCHK_FSCTL
Definition: ext2fs.h:328
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
FAST_IO_POSSIBLE Ext2IsFastIoPossible(IN PEXT2_FCB Fcb)
Definition: fastio.c:38
#define S_IFLNK
Definition: ext2fs.h:360
#define EXT4_EXTENTS_FL
Definition: ext3_fs.h:263
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1675
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1676
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:419
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1999
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1305
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:349
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG FsControlCode
Definition: fltkernel.h:1370
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
_In_ LONGLONG Vbn
Definition: fsrtlfuncs.h:470
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLboolean GLuint group
Definition: glext.h:11120
GLenum GLsizei len
Definition: glext.h:6722
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:90
#define USHRT_MAX
Definition: limits.h:38
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: vista.c:17
NTSTATUS NTAPI CcWaitForCurrentLazyWriterActivity(VOID)
Definition: lazyrite.c:30
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define SE_TCB_PRIVILEGE
Definition: security.c:661
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:38
#define FSCTL_QUERY_RETRIEVAL_POINTERS
Definition: nt_native.h:840
#define FSCTL_OPLOCK_BREAK_NOTIFY
Definition: nt_native.h:831
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE
Definition: nt_native.h:829
#define FSCTL_REQUEST_OPLOCK_LEVEL_1
Definition: nt_native.h:826
#define FSCTL_MARK_VOLUME_DIRTY
Definition: nt_native.h:838
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_REQUEST_BATCH_OPLOCK
Definition: nt_native.h:828
#define FSCTL_OPBATCH_ACK_CLOSE_PENDING
Definition: nt_native.h:830
#define FSCTL_OPLOCK_BREAK_ACK_NO_2
Definition: nt_native.h:846
#define FSCTL_IS_VOLUME_MOUNTED
Definition: nt_native.h:836
#define FSCTL_REQUEST_OPLOCK_LEVEL_2
Definition: nt_native.h:827
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
struct _DISK_GEOMETRY DISK_GEOMETRY
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:753
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:279
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
NTSTATUS NTAPI FsRtlOplockFsctrl(IN POPLOCK Oplock, IN PIRP Irp, IN ULONG OpenCount)
Definition: oplock.c:1430
unsigned short USHORT
Definition: pedump.c:61
#define Vcb
Definition: cdprocs.h:1415
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:746
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:747
struct STARTING_VCN_INPUT_BUFFER * PSTARTING_VCN_INPUT_BUFFER
#define FSCTL_IS_VOLUME_DIRTY
Definition: winioctl.h:755
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:744
#define FSCTL_DELETE_REPARSE_POINT
Definition: winioctl.h:748
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:166
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FSCTL_ALLOW_EXTENDED_DASD_IO
Definition: winioctl.h:124
static FILE * out
Definition: regtests2xml.c:44
#define memset(x, y, z)
Definition: compat.h:39
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4361
int zero
Definition: sehframes.cpp:29
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
uint64 Length
Definition: DriveVolume.h:48
Definition: xml2sdb.h:80
ULONG Type
Definition: ntfs.h:95
ULONG Size
Definition: ntfs.h:96
LARGE_INTEGER StartingVcn
Definition: winioctl.h:782
struct RETRIEVAL_POINTERS_BUFFER::@3331 Extents[1]
LARGE_INTEGER StartingVcn
Definition: winioctl.h:792
PVOID DeviceExtension
Definition: env_spec_w32.h:418
ERESOURCE Resource
Definition: ext2fs.h:519
ULONG Flags
Definition: ext2fs.h:523
LIST_ENTRY VcbList
Definition: ext2fs.h:545
PEXT2_FCB Fcb
Definition: ext2fs.h:914
ULONG Flags
Definition: ntfs.h:536
PVCB Vcb
Definition: cdstruc.h:933
CD_MCB Mcb
Definition: cdstruc.h:1016
ERESOURCE PagingIoResource
Definition: ntfs.h:527
NTFSIDENTIFIER Identifier
Definition: ntfs.h:515
struct _FCB::@734::@737 Fcb
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG OpenHandleCount
Definition: ntfs.h:537
ERESOURCE MainResource
Definition: ntfs.h:528
struct _IO_STACK_LOCATION::@3983::@3998 FileSystemControl
struct _IO_STACK_LOCATION::@3983::@4003 MountVolume
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
union _IO_STACK_LOCATION::@1584 Parameters
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _REPARSE_DATA_BUFFER::@313::@315 SymbolicLinkReparseBuffer
WCHAR PathBuffer[1]
Definition: shellext.h:176
USHORT SubstituteNameOffset
Definition: shellext.h:171
UCHAR DataBuffer[1]
Definition: shellext.h:188
USHORT MaximumLength
Definition: env_spec_w32.h:370
PVPB Vpb
Definition: cdstruc.h:511
Definition: iotypes.h:189
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH/sizeof(WCHAR)]
Definition: iotypes.h:198
USHORT VolumeLabelLength
Definition: iotypes.h:193
ULONG SerialNumber
Definition: iotypes.h:196
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int64_t LONGLONG
Definition: typedefs.h:68
union _LARGE_INTEGER LARGE_INTEGER
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
union _LARGE_INTEGER * PLARGE_INTEGER
Definition: file.c:85
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PEXTENDED_IO_STACK_LOCATION
Definition: udffs.h:119
STRING OEM_STRING
Definition: umtypes.h:203
LONGLONG QuadPart
Definition: typedefs.h:114
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
static BOOL bVerify
Definition: verify.c:27
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT _In_ PDEVICE_OBJECT TargetDevice
Definition: iofuncs.h:691
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define FILE_ACTION_MODIFIED
#define IO_TYPE_VPB
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define VPB_PERSISTENT
Definition: iotypes.h:1809
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MJ_SET_EA
struct _VPB VPB
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IRP_MJ_FLUSH_BUFFERS
#define VPB_LOCKED
Definition: iotypes.h:1808
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415
#define MmGetSystemAddressForMdl(Mdl)
#define ObDereferenceObject
Definition: obfuncs.h:203
ret QuadPart
Definition: rtlfuncs.h:3106
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180