ReactOS 0.4.17-dev-1190-g4c812f4
fsctl.c File Reference
#include "ntfs.h"
#include <ntdddisk.h>
#include <debug.h>
Include dependency graph for fsctl.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS NtfsHasFileSystem (PDEVICE_OBJECT DeviceToMount)
 
static ULONG NtfsQueryMftZoneReservation (VOID)
 
static NTSTATUS NtfsGetVolumeData (PDEVICE_OBJECT DeviceObject, PDEVICE_EXTENSION DeviceExt)
 
static NTSTATUS NtfsMountVolume (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
static NTSTATUS NtfsVerifyVolume (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
static NTSTATUS GetNfsVolumeData (PDEVICE_EXTENSION DeviceExt, PIRP Irp)
 
static NTSTATUS GetNtfsFileRecord (PDEVICE_EXTENSION DeviceExt, PIRP Irp)
 
static NTSTATUS GetVolumeBitmap (PDEVICE_EXTENSION DeviceExt, PIRP Irp)
 
static NTSTATUS LockOrUnlockVolume (PDEVICE_EXTENSION DeviceExt, PIRP Irp, BOOLEAN Lock)
 
NtfsDismountVolume

@implemented

Takes the volume offline so the caller can reformat or eject the media.

Parameters
DeviceExtVolume control block of the volume to dismount
IrpThe FSCTL_DISMOUNT_VOLUME request
Returns
STATUS_SUCCESS once the volume is offline, STATUS_INVALID_PARAMETER if the request did not come through a handle on the volume itself, or STATUS_VOLUME_DISMOUNTED if it already was.
Remarks
The VCB is not torn down here: the caller keeps its handle open and goes on writing over the volume through it, so the device object has to stay alive. What changes is that the volume is no longer mounted, VPB_DIRECT_WRITES_ALLOWED lets raw writes through, and anything needing on-disk metadata is refused.
static NTSTATUS NtfsDismountVolume (PDEVICE_EXTENSION DeviceExt, PIRP Irp)
 
static NTSTATUS NtfsUserFsRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NtfsFileSystemControl (PNTFS_IRP_CONTEXT IrpContext)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 34 of file fsctl.c.

Function Documentation

◆ GetNfsVolumeData()

static NTSTATUS GetNfsVolumeData ( PDEVICE_EXTENSION  DeviceExt,
PIRP  Irp 
)
static

Definition at line 620 of file fsctl.c.

622{
624 PNTFS_VOLUME_DATA_BUFFER DataBuffer;
625 PNTFS_ATTR_RECORD Attribute;
628
629 DataBuffer = (PNTFS_VOLUME_DATA_BUFFER)Irp->AssociatedIrp.SystemBuffer;
631
632 if (Stack->Parameters.FileSystemControl.OutputBufferLength < sizeof(NTFS_VOLUME_DATA_BUFFER) ||
633 Irp->UserBuffer == NULL)
634 {
635 DPRINT1("Invalid output! %d %p\n", Stack->Parameters.FileSystemControl.OutputBufferLength, Irp->UserBuffer);
637 }
638
639 DataBuffer->VolumeSerialNumber.QuadPart = DeviceExt->NtfsInfo.SerialNumber;
640 DataBuffer->NumberSectors.QuadPart = DeviceExt->NtfsInfo.SectorCount;
641 DataBuffer->TotalClusters.QuadPart = DeviceExt->NtfsInfo.ClusterCount;
642 DataBuffer->FreeClusters.QuadPart = NtfsGetFreeClusters(DeviceExt);
643 DataBuffer->TotalReserved.QuadPart = 0LL; // FIXME
644 DataBuffer->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
645 DataBuffer->BytesPerCluster = DeviceExt->NtfsInfo.BytesPerCluster;
646 DataBuffer->BytesPerFileRecordSegment = DeviceExt->NtfsInfo.BytesPerFileRecord;
647 DataBuffer->ClustersPerFileRecordSegment = DeviceExt->NtfsInfo.BytesPerFileRecord / DeviceExt->NtfsInfo.BytesPerCluster;
648 DataBuffer->MftStartLcn.QuadPart = DeviceExt->NtfsInfo.MftStart.QuadPart;
649 DataBuffer->Mft2StartLcn.QuadPart = DeviceExt->NtfsInfo.MftMirrStart.QuadPart;
650 DataBuffer->MftZoneStart.QuadPart = 0; // FIXME
651 DataBuffer->MftZoneEnd.QuadPart = 0; // FIXME
652
653 Status = FindFirstAttribute(&Context, DeviceExt, DeviceExt->MasterFileTable, FALSE, &Attribute);
654 while (NT_SUCCESS(Status))
655 {
656 if (Attribute->Type == AttributeData)
657 {
658 ASSERT(Attribute->IsNonResident);
659 DataBuffer->MftValidDataLength.QuadPart = Attribute->NonResident.DataSize;
660
661 break;
662 }
663
664 Status = FindNextAttribute(&Context, &Attribute);
665 }
667
668 Irp->IoStatus.Information = sizeof(NTFS_VOLUME_DATA_BUFFER);
669
670 if (Stack->Parameters.FileSystemControl.OutputBufferLength >= sizeof(NTFS_EXTENDED_VOLUME_DATA) + sizeof(NTFS_VOLUME_DATA_BUFFER))
671 {
673
674 ExtendedData->ByteCount = sizeof(NTFS_EXTENDED_VOLUME_DATA);
675 ExtendedData->MajorVersion = DeviceExt->NtfsInfo.MajorVersion;
676 ExtendedData->MinorVersion = DeviceExt->NtfsInfo.MinorVersion;
677 Irp->IoStatus.Information += sizeof(NTFS_EXTENDED_VOLUME_DATA);
678 }
679
680 return STATUS_SUCCESS;
681}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1413
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1495
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1461
ULONGLONG NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt)
Definition: volinfo.c:193
@ AttributeData
Definition: ntfs.h:195
Status
Definition: gdiplustypes.h:24
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ASSERT(a)
Definition: mode.c:44
struct NTFS_VOLUME_DATA_BUFFER * PNTFS_VOLUME_DATA_BUFFER
struct NTFS_EXTENDED_VOLUME_DATA * PNTFS_EXTENDED_VOLUME_DATA
#define STATUS_SUCCESS
Definition: shellext.h:65
struct NTFS_ATTR_RECORD::@170::@173 NonResident
UCHAR IsNonResident
Definition: ntfs.h:136
ULONG Type
Definition: ntfs.h:134
LARGE_INTEGER NumberSectors
Definition: winioctl.h:808
LARGE_INTEGER MftValidDataLength
Definition: winioctl.h:816
LARGE_INTEGER TotalReserved
Definition: winioctl.h:811
LARGE_INTEGER Mft2StartLcn
Definition: winioctl.h:818
LARGE_INTEGER FreeClusters
Definition: winioctl.h:810
DWORD BytesPerFileRecordSegment
Definition: winioctl.h:814
LARGE_INTEGER MftZoneStart
Definition: winioctl.h:819
DWORD ClustersPerFileRecordSegment
Definition: winioctl.h:815
LARGE_INTEGER TotalClusters
Definition: winioctl.h:809
LARGE_INTEGER VolumeSerialNumber
Definition: winioctl.h:807
LARGE_INTEGER MftZoneEnd
Definition: winioctl.h:820
LARGE_INTEGER MftStartLcn
Definition: winioctl.h:817
#define LL
Definition: tui.h:167
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

Referenced by NtfsUserFsRequest().

◆ GetNtfsFileRecord()

static NTSTATUS GetNtfsFileRecord ( PDEVICE_EXTENSION  DeviceExt,
PIRP  Irp 
)
static

Definition at line 686 of file fsctl.c.

688{
692 PFILE_RECORD_HEADER FileRecord;
694 ULONGLONG MFTRecord;
695
697
698 if (Stack->Parameters.FileSystemControl.InputBufferLength < sizeof(NTFS_FILE_RECORD_INPUT_BUFFER) ||
699 Irp->AssociatedIrp.SystemBuffer == NULL)
700 {
701 DPRINT1("Invalid input! %d %p\n", Stack->Parameters.FileSystemControl.InputBufferLength, Irp->AssociatedIrp.SystemBuffer);
703 }
704
705 if (Stack->Parameters.FileSystemControl.OutputBufferLength < (FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER, FileRecordBuffer) + DeviceExt->NtfsInfo.BytesPerFileRecord) ||
706 Irp->AssociatedIrp.SystemBuffer == NULL)
707 {
708 DPRINT1("Invalid output! %d %p\n", Stack->Parameters.FileSystemControl.OutputBufferLength, Irp->AssociatedIrp.SystemBuffer);
710 }
711
712 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
713 if (FileRecord == NULL)
714 {
716 }
717
718 InputBuffer = (PNTFS_FILE_RECORD_INPUT_BUFFER)Irp->AssociatedIrp.SystemBuffer;
719
720 MFTRecord = InputBuffer->FileReferenceNumber.QuadPart;
721 DPRINT1("Requesting: %I64x\n", MFTRecord);
722
723 do
724 {
725 Status = ReadFileRecord(DeviceExt, MFTRecord, FileRecord);
726 if (NT_SUCCESS(Status))
727 {
728 if (FileRecord->Flags & FRH_IN_USE)
729 {
730 break;
731 }
732 }
733
734 --MFTRecord;
735 } while (TRUE);
736
737 DPRINT1("Returning: %I64x\n", MFTRecord);
738 OutputBuffer = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)Irp->AssociatedIrp.SystemBuffer;
739 OutputBuffer->FileReferenceNumber.QuadPart = MFTRecord;
740 OutputBuffer->FileRecordLength = DeviceExt->NtfsInfo.BytesPerFileRecord;
741 RtlCopyMemory(OutputBuffer->FileRecordBuffer, FileRecord, DeviceExt->NtfsInfo.BytesPerFileRecord);
742
743 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
744
745 Irp->IoStatus.Information = FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER, FileRecordBuffer) + DeviceExt->NtfsInfo.BytesPerFileRecord;
746
747 return STATUS_SUCCESS;
748}
#define TRUE
Definition: types.h:120
#define FRH_IN_USE
Definition: ntfs.h:298
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1936
struct NTFS_FILE_RECORD_OUTPUT_BUFFER * PNTFS_FILE_RECORD_OUTPUT_BUFFER
struct NTFS_FILE_RECORD_INPUT_BUFFER * PNTFS_FILE_RECORD_INPUT_BUFFER
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
USHORT Flags
Definition: ntfs.h:287
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_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 InputBuffer
Definition: wdfiotarget.h:953

Referenced by NtfsUserFsRequest().

◆ GetVolumeBitmap()

static NTSTATUS GetVolumeBitmap ( PDEVICE_EXTENSION  DeviceExt,
PIRP  Irp 
)
static

Definition at line 753 of file fsctl.c.

755{
759 LONGLONG StartingLcn;
760 ULONGLONG TotalClusters;
761 ULONGLONG ToCopy;
762 BOOLEAN Overflow = FALSE;
763
764 DPRINT("GetVolumeBitmap(%p, %p)\n", DeviceExt, Irp);
765
767
768 if (Stack->Parameters.FileSystemControl.InputBufferLength < sizeof(STARTING_LCN_INPUT_BUFFER))
769 {
770 DPRINT1("Invalid input! %d\n", Stack->Parameters.FileSystemControl.InputBufferLength);
772 }
773
774 if (Stack->Parameters.FileSystemControl.OutputBufferLength < sizeof(VOLUME_BITMAP_BUFFER))
775 {
776 DPRINT1("Invalid output! %d\n", Stack->Parameters.FileSystemControl.OutputBufferLength);
778 }
779
781 if (Irp->RequestorMode == UserMode)
782 {
784 {
785 ProbeForRead(Stack->Parameters.FileSystemControl.Type3InputBuffer,
786 Stack->Parameters.FileSystemControl.InputBufferLength,
787 sizeof(CHAR));
788 ProbeForWrite(BitmapBuffer, Stack->Parameters.FileSystemControl.OutputBufferLength,
789 sizeof(CHAR));
790 }
792 {
794 }
795 _SEH2_END;
796 }
797 else
798 {
799 if (Stack->Parameters.FileSystemControl.Type3InputBuffer == NULL ||
801 {
803 }
804 }
805
806 if (!NT_SUCCESS(Status))
807 {
808 DPRINT1("Invalid buffer! %p %p\n", Stack->Parameters.FileSystemControl.Type3InputBuffer, BitmapBuffer);
809 return Status;
810 }
811
812 StartingLcn = ((PSTARTING_LCN_INPUT_BUFFER)Stack->Parameters.FileSystemControl.Type3InputBuffer)->StartingLcn.QuadPart;
813 if (StartingLcn > DeviceExt->NtfsInfo.ClusterCount)
814 {
815 DPRINT1("Requested bitmap start beyond partition end: %I64x %I64x\n", DeviceExt->NtfsInfo.ClusterCount, StartingLcn);
817 }
818
819 /* Round down to a multiple of 8 */
820 StartingLcn = StartingLcn & ~7;
821 TotalClusters = DeviceExt->NtfsInfo.ClusterCount - StartingLcn;
822 ToCopy = TotalClusters / 8;
823 if ((ToCopy + FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer)) > Stack->Parameters.FileSystemControl.OutputBufferLength)
824 {
825 DPRINT1("Buffer too small: %x, needed: %x\n", Stack->Parameters.FileSystemControl.OutputBufferLength, (ToCopy + FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer)));
826 Overflow = TRUE;
827 ToCopy = Stack->Parameters.FileSystemControl.OutputBufferLength - FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer);
828 }
829
830 BitmapBuffer->StartingLcn.QuadPart = StartingLcn;
831 BitmapBuffer->BitmapSize.QuadPart = ToCopy * 8;
832
833 Irp->IoStatus.Information = FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer);
834
836 ExAcquireResourceSharedLite(&DeviceExt->BitmapResource, TRUE);
838 {
839 RtlCopyMemory(BitmapBuffer->Buffer, (PUCHAR)DeviceExt->BitmapBuffer + StartingLcn / 8, (SIZE_T)ToCopy);
840 Irp->IoStatus.Information += (ULONG_PTR)ToCopy;
842 }
844 {
846 }
847 _SEH2_END;
848 ExReleaseResourceLite(&DeviceExt->BitmapResource);
850
851 return Status;
852}
unsigned char BOOLEAN
Definition: actypes.h:127
Definition: bufpool.h:45
PVOID NtfsGetUserBuffer(PIRP Irp, BOOLEAN Paging)
Definition: misc.c:120
#define ULONG_PTR
Definition: config.h:101
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
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
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define UserMode
Definition: asm.h:39
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
char CHAR
Definition: pedump.c:57
struct STARTING_LCN_INPUT_BUFFER * PSTARTING_LCN_INPUT_BUFFER
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
int64_t LONGLONG
Definition: typedefs.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by NtfsUserFsRequest().

◆ LockOrUnlockVolume()

static NTSTATUS LockOrUnlockVolume ( PDEVICE_EXTENSION  DeviceExt,
PIRP  Irp,
BOOLEAN  Lock 
)
static

Definition at line 857 of file fsctl.c.

860{
864
865 DPRINT("LockOrUnlockVolume(%p, %p, %d)\n", DeviceExt, Irp, Lock);
866
868 FileObject = Stack->FileObject;
869 Fcb = FileObject->FsContext;
870
871 /* Only allow locking with the volume open */
872 if (!(Fcb->Flags & FCB_IS_VOLUME))
873 {
875 }
876
877 /* Bail out if it's already in the demanded state */
878 if (((DeviceExt->Flags & VCB_VOLUME_LOCKED) && Lock) ||
879 (!(DeviceExt->Flags & VCB_VOLUME_LOCKED) && !Lock))
880 {
882 }
883
884 /* Deny locking if we're not alone */
885 if (Lock && DeviceExt->OpenHandleCount != 1)
886 {
888 }
889
890 /* Finally, proceed */
891 if (Lock)
892 {
893 DeviceExt->Flags |= VCB_VOLUME_LOCKED;
894 }
895 else
896 {
897 DeviceExt->Flags &= ~VCB_VOLUME_LOCKED;
898 }
899
900 return STATUS_SUCCESS;
901}
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define FCB_IS_VOLUME
Definition: ntfs.h:585
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:789
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:618
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by NtfsUserFsRequest().

◆ NtfsDismountVolume()

static NTSTATUS NtfsDismountVolume ( PDEVICE_EXTENSION  DeviceExt,
PIRP  Irp 
)
static

Definition at line 930 of file fsctl.c.

932{
936 KIRQL SavedIrql;
937
939 FileObject = Stack->FileObject;
940 Fcb = FileObject->FsContext;
941
942 /* Only a handle on the volume itself may dismount it */
943 if (!(Fcb->Flags & FCB_IS_VOLUME))
944 {
946 }
947
948 if (DeviceExt->Flags & VCB_VOLUME_DISMOUNTED)
949 {
951 }
952
953 DPRINT1("Dismounting volume\n");
954
956
957 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
958
959 DeviceExt->Flags |= VCB_VOLUME_DISMOUNTED;
960
961 /* Drop the mounted state and allow raw writes, so the I/O manager stops
962 * handing us opens of a partition that's being overwritten */
963 IoAcquireVpbSpinLock(&SavedIrql);
964 if (DeviceExt->StorageDevice->Vpb != NULL)
965 {
966 DeviceExt->StorageDevice->Vpb->Flags |= VPB_DIRECT_WRITES_ALLOWED;
967 DeviceExt->StorageDevice->Vpb->Flags &= ~VPB_MOUNTED;
968 }
969 IoReleaseVpbSpinLock(SavedIrql);
970
971 ExReleaseResourceLite(&DeviceExt->DirResource);
972
973 return STATUS_SUCCESS;
974}
#define VCB_VOLUME_DISMOUNTED
Definition: ntfs.h:148
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define FSRTL_VOLUME_DISMOUNT
Definition: ntifs_ex.h:439
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
Definition: pnp.c:38
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:869
#define VPB_DIRECT_WRITES_ALLOWED
Definition: iotypes.h:1812

Referenced by NtfsUserFsRequest().

◆ NtfsFileSystemControl()

NTSTATUS NtfsFileSystemControl ( PNTFS_IRP_CONTEXT  IrpContext)

Definition at line 1045 of file fsctl.c.

1046{
1048 PIRP Irp;
1050
1051 DPRINT("NtfsFileSystemControl() called\n");
1052
1053 DeviceObject = IrpContext->DeviceObject;
1054 Irp = IrpContext->Irp;
1056
1057 switch (IrpContext->MinorFunction)
1058 {
1059 case IRP_MN_KERNEL_CALL:
1060 DPRINT1("NTFS: IRP_MN_USER_FS_REQUEST\n");
1062 break;
1063
1066 break;
1067
1069 DPRINT("NTFS: IRP_MN_MOUNT_VOLUME\n");
1071 break;
1072
1074 DPRINT1("NTFS: IRP_MN_VERIFY_VOLUME\n");
1076 break;
1077
1078 default:
1079 DPRINT1("NTFS FSC: MinorFunction %d\n", IrpContext->MinorFunction);
1081 break;
1082 }
1083
1084 return Status;
1085}
static NTSTATUS NtfsVerifyVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fsctl.c:608
static NTSTATUS NtfsMountVolume(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fsctl.c:427
static NTSTATUS NtfsUserFsRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fsctl.c:978
UCHAR MinorFunction
Definition: ntfs.h:559
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:563
IO_STATUS_BLOCK IoStatus
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4421
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4419
#define IRP_MN_KERNEL_CALL
Definition: iotypes.h:4424
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4420

Referenced by NtfsDispatch().

◆ NtfsGetVolumeData()

static NTSTATUS NtfsGetVolumeData ( PDEVICE_OBJECT  DeviceObject,
PDEVICE_EXTENSION  DeviceExt 
)
static

Definition at line 194 of file fsctl.c.

196{
197 DISK_GEOMETRY DiskGeometry;
198 PFILE_RECORD_HEADER VolumeRecord;
201 ULONG Size;
202 PNTFS_INFO NtfsInfo = &DeviceExt->NtfsInfo;
204 PNTFS_ATTR_CONTEXT AttrCtxt;
205 PNTFS_ATTR_RECORD Attribute;
206 PNTFS_FCB VolumeFcb;
207 PWSTR VolumeNameU;
208
209 DPRINT("NtfsGetVolumeData() called\n");
210
211 Size = sizeof(DISK_GEOMETRY);
214 NULL,
215 0,
216 &DiskGeometry,
217 &Size,
218 TRUE);
219 if (!NT_SUCCESS(Status))
220 {
221 DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
222 return Status;
223 }
224
225 DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
227 DiskGeometry.BytesPerSector,
228 TAG_NTFS);
229 if (BootSector == NULL)
230 {
232 }
233
235 0, /* Partition boot sector */
236 1,
237 DiskGeometry.BytesPerSector,
239 TRUE);
240 if (!NT_SUCCESS(Status))
241 {
243 return Status;
244 }
245
246 /* Read data from the bootsector */
250 NtfsInfo->SectorCount = BootSector->EBPB.SectorCount;
251 NtfsInfo->ClusterCount = DeviceExt->NtfsInfo.SectorCount / (ULONGLONG)DeviceExt->NtfsInfo.SectorsPerCluster;
252
253 NtfsInfo->MftStart.QuadPart = BootSector->EBPB.MftLocation;
254 NtfsInfo->MftMirrStart.QuadPart = BootSector->EBPB.MftMirrLocation;
255 NtfsInfo->SerialNumber = BootSector->EBPB.SerialNumber;
256 if (BootSector->EBPB.ClustersPerMftRecord > 0)
257 NtfsInfo->BytesPerFileRecord = BootSector->EBPB.ClustersPerMftRecord * NtfsInfo->BytesPerCluster;
258 else
259 NtfsInfo->BytesPerFileRecord = 1 << (-BootSector->EBPB.ClustersPerMftRecord);
260 if (BootSector->EBPB.ClustersPerIndexRecord > 0)
261 NtfsInfo->BytesPerIndexRecord = BootSector->EBPB.ClustersPerIndexRecord * NtfsInfo->BytesPerCluster;
262 else
263 NtfsInfo->BytesPerIndexRecord = 1 << (-BootSector->EBPB.ClustersPerIndexRecord);
264
265 DPRINT("Boot sector information:\n");
266 DPRINT(" BytesPerSector: %hu\n", BootSector->BPB.BytesPerSector);
267 DPRINT(" SectorsPerCluster: %hu\n", BootSector->BPB.SectorsPerCluster);
268 DPRINT(" SectorCount: %I64u\n", BootSector->EBPB.SectorCount);
269 DPRINT(" MftStart: %I64u\n", BootSector->EBPB.MftLocation);
270 DPRINT(" MftMirrStart: %I64u\n", BootSector->EBPB.MftMirrLocation);
271 DPRINT(" ClustersPerMftRecord: %lx\n", BootSector->EBPB.ClustersPerMftRecord);
272 DPRINT(" ClustersPerIndexRecord: %lx\n", BootSector->EBPB.ClustersPerIndexRecord);
273 DPRINT(" SerialNumber: %I64x\n", BootSector->EBPB.SerialNumber);
274
276
277 ExInitializeNPagedLookasideList(&DeviceExt->FileRecLookasideList,
278 NULL, NULL, 0, NtfsInfo->BytesPerFileRecord, TAG_FILE_REC, 0);
279
280 DeviceExt->MasterFileTable = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
281 if (DeviceExt->MasterFileTable == NULL)
282 {
283 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
285 }
286
288 NtfsInfo->MftStart.u.LowPart * NtfsInfo->SectorsPerCluster,
289 NtfsInfo->BytesPerFileRecord / NtfsInfo->BytesPerSector,
290 NtfsInfo->BytesPerSector,
291 (PVOID)DeviceExt->MasterFileTable,
292 TRUE);
293 if (!NT_SUCCESS(Status))
294 {
295 DPRINT1("Failed reading MFT.\n");
296 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, DeviceExt->MasterFileTable);
297 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
298 return Status;
299 }
300
301 /* A non-resident attribute list in $MFT is read through this */
302 DeviceExt->StorageDevice = DeviceObject;
303
304 Status = FindAttribute(DeviceExt,
305 DeviceExt->MasterFileTable,
307 L"",
308 0,
309 &DeviceExt->MFTContext,
310 &DeviceExt->MftDataOffset);
311 if (!NT_SUCCESS(Status))
312 {
313 DPRINT1("Can't find data attribute for Master File Table.\n");
314 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, DeviceExt->MasterFileTable);
315 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
316 return Status;
317 }
318
319 VolumeRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
320 if (VolumeRecord == NULL)
321 {
322 DPRINT1("Allocation failed for volume record\n");
323 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, DeviceExt->MasterFileTable);
324 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
326 }
327
328 /* Read Volume File (MFT index 3) */
329 Status = ReadFileRecord(DeviceExt,
331 VolumeRecord);
332 if (!NT_SUCCESS(Status))
333 {
334 DPRINT1("Failed reading volume file\n");
335 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, VolumeRecord);
336 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, DeviceExt->MasterFileTable);
337 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
338 return Status;
339 }
340
341 /* Enumerate attributes */
342 NtfsDumpFileAttributes(DeviceExt, DeviceExt->MasterFileTable);
343
344 /* Enumerate attributes */
345 NtfsDumpFileAttributes(DeviceExt, VolumeRecord);
346
347 /* Get volume name */
348 Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeName, L"", 0, &AttrCtxt, NULL);
349
350 if (NT_SUCCESS(Status) && AttrCtxt->pRecord->Resident.ValueLength != 0)
351 {
352 Attribute = AttrCtxt->pRecord;
353 DPRINT("Data length %lu\n", AttributeDataLength(Attribute));
354 NtfsInfo->VolumeLabelLength =
355 min (Attribute->Resident.ValueLength, MAXIMUM_VOLUME_LABEL_LENGTH);
356 RtlCopyMemory(NtfsInfo->VolumeLabel,
357 (PVOID)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset),
358 NtfsInfo->VolumeLabelLength);
359 VolumeNameU = NtfsInfo->VolumeLabel;
360 }
361 else
362 {
363 NtfsInfo->VolumeLabelLength = 0;
364 VolumeNameU = L"\0";
365 }
366
367 if (NT_SUCCESS(Status))
368 {
369 ReleaseAttributeContext(AttrCtxt);
370 }
371
372 VolumeFcb = NtfsCreateFCB(VolumeNameU, NULL, DeviceExt);
373 if (VolumeFcb == NULL)
374 {
375 DPRINT1("Failed allocating volume FCB\n");
376 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, VolumeRecord);
377 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, DeviceExt->MasterFileTable);
378 ExDeleteNPagedLookasideList(&DeviceExt->FileRecLookasideList);
380 }
381
382 VolumeFcb->Flags = FCB_IS_VOLUME;
383 VolumeFcb->RFCB.FileSize.QuadPart = DeviceExt->NtfsInfo.SectorCount * DeviceExt->NtfsInfo.BytesPerSector;
384 VolumeFcb->RFCB.ValidDataLength = VolumeFcb->RFCB.FileSize;
385 VolumeFcb->RFCB.AllocationSize = VolumeFcb->RFCB.FileSize;
386 VolumeFcb->MFTIndex = 0;
387 DeviceExt->VolumeFcb = VolumeFcb;
388
389 /* Get volume information */
390 Status = FindAttribute(DeviceExt, VolumeRecord, AttributeVolumeInformation, L"", 0, &AttrCtxt, NULL);
391
392 if (NT_SUCCESS(Status) && AttrCtxt->pRecord->Resident.ValueLength != 0)
393 {
394 Attribute = AttrCtxt->pRecord;
395 DPRINT("Data length %lu\n", AttributeDataLength (Attribute));
396 VolumeInfo = (PVOID)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
397
398 NtfsInfo->MajorVersion = VolumeInfo->MajorVersion;
399 NtfsInfo->MinorVersion = VolumeInfo->MinorVersion;
400 NtfsInfo->Flags = VolumeInfo->Flags;
401 }
402
403 if (NT_SUCCESS(Status))
404 {
405 ReleaseAttributeContext(AttrCtxt);
406 }
407
408 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, VolumeRecord);
409
411
412 /* NTFS defines its own case folding through $UpCase; without it every
413 * case-insensitive comparison on this volume would use the wrong table. */
414 Status = NtfsLoadUpCaseTable(DeviceExt);
415 if (!NT_SUCCESS(Status))
416 {
417 DPRINT1("Failed to load $UpCase (Status %lx)\n", Status);
418 return Status;
419 }
420
421 return Status;
422}
#define NTFS_FILE_VOLUME
Definition: ntfs.h:26
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define L(x)
Definition: resources.c:13
VOID NtfsDumpFileAttributes(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:1820
@ AttributeVolumeName
Definition: ntfs.h:193
@ AttributeVolumeInformation
Definition: ntfs.h:194
#define TAG_FILE_REC
Definition: ntfs.h:17
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
NTSTATUS NtfsLoadUpCaseTable(PDEVICE_EXTENSION Vcb)
Definition: mft.c:1930
#define min(a, b)
Definition: monoChain.cc:55
struct _DISK_GEOMETRY DISK_GEOMETRY
NTSTATUS NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
Definition: blockdev.c:1011
NTSTATUS NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG ControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG OutputBufferSize, IN BOOLEAN Override)
Definition: blockdev.c:1029
PNTFS_FCB NtfsCreateFCB(PCWSTR FileName, PCWSTR Stream, PNTFS_VCB Vcb)
Definition: fcb.c:67
static ULONG NtfsQueryMftZoneReservation(VOID)
Definition: fsctl.c:172
struct NTFS_ATTR_RECORD::@170::@172 Resident
unsigned short BytesPerSector
Definition: vfat.h:42
unsigned char SectorsPerCluster
Definition: vfat.h:43
ULONG BytesPerSector
Definition: ntdddisk.h:404
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
ULONGLONG MFTIndex
Definition: ntfs.h:622
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
ULARGE_INTEGER MftStart
Definition: ntfs.h:73
ULONG BytesPerCluster
Definition: ntfs.h:70
USHORT VolumeLabelLength
Definition: ntfs.h:79
ULONG BytesPerFileRecord
Definition: ntfs.h:75
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH]
Definition: ntfs.h:80
ULONG BytesPerIndexRecord
Definition: ntfs.h:76
USHORT Flags
Definition: ntfs.h:83
ULONGLONG ClusterCount
Definition: ntfs.h:72
ULONG BytesPerSector
Definition: ntfs.h:68
ULARGE_INTEGER MftMirrStart
Definition: ntfs.h:74
UCHAR MinorVersion
Definition: ntfs.h:82
ULONGLONG SerialNumber
Definition: ntfs.h:78
ULONG MftZoneReservation
Definition: ntfs.h:85
ULONG SectorsPerCluster
Definition: ntfs.h:69
UCHAR MajorVersion
Definition: ntfs.h:81
ULONGLONG SectorCount
Definition: ntfs.h:71
struct _ULARGE_INTEGER::@5176 u
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
uint16_t * PWSTR
Definition: typedefs.h:56
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
struct _BootSector BootSector
Definition: vfat.h:108
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: volutil.h:12
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by NtfsMountVolume().

◆ NtfsHasFileSystem()

static NTSTATUS NtfsHasFileSystem ( PDEVICE_OBJECT  DeviceToMount)
static

Definition at line 45 of file fsctl.c.

46{
48 DISK_GEOMETRY DiskGeometry;
52
53 DPRINT("NtfsHasFileSystem() called\n");
54
55 Size = sizeof(DISK_GEOMETRY);
56 Status = NtfsDeviceIoControl(DeviceToMount,
58 NULL,
59 0,
60 &DiskGeometry,
61 &Size,
62 TRUE);
63 if (!NT_SUCCESS(Status))
64 {
65 DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
66 return Status;
67 }
68
69 if (DiskGeometry.MediaType == FixedMedia)
70 {
71 /* We have found a hard disk */
73 Status = NtfsDeviceIoControl(DeviceToMount,
75 NULL,
76 0,
78 &Size,
79 TRUE);
80 if (!NT_SUCCESS(Status))
81 {
82 DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
83 return Status;
84 }
85
86 if (PartitionInfo.PartitionType != PARTITION_IFS)
87 {
88 DPRINT1("Invalid partition type\n");
90 }
91 }
92
93 DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
95 DiskGeometry.BytesPerSector,
96 TAG_NTFS);
97 if (BootSector == NULL)
98 {
100 }
101
102 Status = NtfsReadSectors(DeviceToMount,
103 0,
104 1,
105 DiskGeometry.BytesPerSector,
107 TRUE);
108 if (!NT_SUCCESS(Status))
109 {
110 goto ByeBye;
111 }
112
113 /*
114 * Check values of different fields. If those fields have not expected
115 * values, we fail, to avoid mounting partitions that Windows won't mount.
116 */
117
118 /* OEMID: this field must be NTFS */
119 if (RtlCompareMemory(BootSector->OEMID, "NTFS ", 8) != 8)
120 {
121 DPRINT1("Failed with NTFS-identifier: [%.8s]\n", BootSector->OEMID);
123 goto ByeBye;
124 }
125
126 /* Unused0: this field must be COMPLETELY null */
127 for (k = 0; k < 7; k++)
128 {
129 if (BootSector->BPB.Unused0[k] != 0)
130 {
131 DPRINT1("Failed in field Unused0: [%.7s]\n", BootSector->BPB.Unused0);
133 goto ByeBye;
134 }
135 }
136
137 /* Unused3: this field must be COMPLETELY null */
138 for (k = 0; k < 4; k++)
139 {
140 if (BootSector->BPB.Unused3[k] != 0)
141 {
142 DPRINT1("Failed in field Unused3: [%.4s]\n", BootSector->BPB.Unused3);
144 goto ByeBye;
145 }
146 }
147
148 /* Check cluster size */
150 if (ClusterSize != 512 && ClusterSize != 1024 &&
151 ClusterSize != 2048 && ClusterSize != 4096 &&
152 ClusterSize != 8192 && ClusterSize != 16384 &&
153 ClusterSize != 32768 && ClusterSize != 65536)
154 {
155 DPRINT1("Cluster size failed: %hu, %hu, %hu\n",
160 goto ByeBye;
161 }
162
163ByeBye:
165
166 return Status;
167}
DWORD ClusterSize
Definition: format.c:66
static const uint32_t k[]
Definition: sha256.c:24
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
struct _PARTITION_INFORMATION PARTITION_INFORMATION
@ FixedMedia
Definition: ntdddisk.h:383
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define PARTITION_IFS
Definition: part_mbr.h:57
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by NtfsMountVolume().

◆ NtfsMountVolume()

static NTSTATUS NtfsMountVolume ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 427 of file fsctl.c.

429{
430 PDEVICE_OBJECT NewDeviceObject = NULL;
431 PDEVICE_OBJECT DeviceToMount;
438
439 DPRINT("NtfsMountVolume() called\n");
440
442 {
444 goto ByeBye;
445 }
446
448 DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
449
450 Status = NtfsHasFileSystem(DeviceToMount);
451 if (!NT_SUCCESS(Status))
452 {
453 goto ByeBye;
454 }
455
457 sizeof(DEVICE_EXTENSION),
458 NULL,
460 0,
461 FALSE,
462 &NewDeviceObject);
463 if (!NT_SUCCESS(Status))
464 goto ByeBye;
465
466 NewDeviceObject->Flags |= DO_DIRECT_IO;
467 Vcb = (PVOID)NewDeviceObject->DeviceExtension;
468 RtlZeroMemory(Vcb, sizeof(NTFS_VCB));
469
470 Vcb->Identifier.Type = NTFS_TYPE_VCB;
471 Vcb->Identifier.Size = sizeof(NTFS_TYPE_VCB);
472
473 Status = NtfsGetVolumeData(DeviceToMount,
474 Vcb);
475 if (!NT_SUCCESS(Status))
476 goto ByeBye;
477
478 Lookaside = TRUE;
479
480 NewDeviceObject->Vpb = DeviceToMount->Vpb;
481
482 Vcb->StorageDevice = DeviceToMount;
483 Vcb->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
484 Vcb->StorageDevice->Vpb->RealDevice = Vcb->StorageDevice;
485 Vcb->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
486 NewDeviceObject->StackSize = Vcb->StorageDevice->StackSize + 1;
487 NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
488
489 Vcb->StreamFileObject = IoCreateStreamFileObject(NULL,
490 Vcb->StorageDevice);
491
492 InitializeListHead(&Vcb->FcbListHead);
493
495 if (Fcb == NULL)
496 {
498 goto ByeBye;
499 }
500
502 sizeof(NTFS_CCB),
503 TAG_CCB);
504 if (Ccb == NULL)
505 {
507 goto ByeBye;
508 }
509
510 RtlZeroMemory(Ccb, sizeof(NTFS_CCB));
511
513 Ccb->Identifier.Size = sizeof(NTFS_TYPE_CCB);
514
515 Vcb->StreamFileObject->FsContext = Fcb;
516 Vcb->StreamFileObject->FsContext2 = Ccb;
517 Vcb->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
518 Vcb->StreamFileObject->PrivateCacheMap = NULL;
519 Vcb->StreamFileObject->Vpb = Vcb->Vpb;
520 Ccb->PtrFileObject = Vcb->StreamFileObject;
521 Fcb->FileObject = Vcb->StreamFileObject;
522 Fcb->Vcb = (PDEVICE_EXTENSION)Vcb->StorageDevice;
523
525
526 Fcb->RFCB.FileSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
527 Fcb->RFCB.ValidDataLength.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
528 Fcb->RFCB.AllocationSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; /* Correct? */
529
530// Fcb->Entry.ExtentLocationL = 0;
531// Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
532
534 {
535 CcInitializeCacheMap(Vcb->StreamFileObject,
537 TRUE,
539 Fcb);
540 }
542 {
544 goto ByeBye;
545 }
546 _SEH2_END;
547
549 if (!NT_SUCCESS(Status))
550 goto ByeBye;
551
552 ExInitializeResourceLite(&Vcb->DirResource);
553 ExInitializeResourceLite(&Vcb->IndexResource);
554 ExInitializeResourceLite(&Vcb->BitmapResource);
555
556 KeInitializeSpinLock(&Vcb->FcbListLock);
557
558 /* Get serial number */
559 NewDeviceObject->Vpb->SerialNumber = Vcb->NtfsInfo.SerialNumber;
560
561 /* Get volume label */
562 NewDeviceObject->Vpb->VolumeLabelLength = Vcb->NtfsInfo.VolumeLabelLength;
563 RtlCopyMemory(NewDeviceObject->Vpb->VolumeLabel,
564 Vcb->NtfsInfo.VolumeLabel,
565 Vcb->NtfsInfo.VolumeLabelLength);
566
568
570
571ByeBye:
572 if (!NT_SUCCESS(Status))
573 {
574 /* Cleanup */
575 if (Vcb && Vcb->StreamFileObject)
576 ObDereferenceObject(Vcb->StreamFileObject);
577
578 if (Fcb)
580
581 if (Ccb)
583
584 if (Vcb != NULL)
586
587 if (Vcb != NULL && Vcb->UpCaseTable != NULL)
588 {
589 ExFreePoolWithTag(Vcb->UpCaseTable, TAG_NTFS);
590 Vcb->UpCaseTable = NULL;
591 }
592
593 if (Lookaside)
594 ExDeleteNPagedLookasideList(&Vcb->FileRecLookasideList);
595
596 if (NewDeviceObject)
597 IoDeleteDevice(NewDeviceObject);
598 }
599
600 DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status);
601
602 return Status;
603}
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define TAG_CCB
Definition: cdprocs.h:85
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
NTSTATUS NtfsLoadVolumeBitmap(_In_ PDEVICE_EXTENSION DeviceExt)
Definition: volinfo.c:49
VOID NtfsFreeVolumeBitmap(_In_ PDEVICE_EXTENSION DeviceExt)
Definition: volinfo.c:132
#define NTFS_TYPE_VCB
Definition: ntfs.h:90
#define FCB_IS_VOLUME_STREAM
Definition: ntfs.h:584
#define NTFS_TYPE_CCB
Definition: ntfs.h:88
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
VOID NtfsDestroyFCB(PNTFS_FCB Fcb)
Definition: fcb.c:126
static NTSTATUS NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
Definition: fsctl.c:45
static NTSTATUS NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject, PDEVICE_EXTENSION DeviceExt)
Definition: fsctl.c:194
#define FSRTL_VOLUME_MOUNT
Definition: ntifs_ex.h:444
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:1038
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1261
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3186
#define Vcb
Definition: cdprocs.h:1415
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
ULONG Type
Definition: ntfs.h:96
ULONG Size
Definition: ntfs.h:97
Definition: ntfs.h:151
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:175
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
Definition: ntfs.h:176
PDRIVER_OBJECT DriverObject
Definition: ntfs.h:174
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PVCB Vcb
Definition: cdstruc.h:933
NTFSIDENTIFIER Identifier
Definition: ntfs.h:595
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
PFILE_OBJECT FileObject
Definition: ntfs.h:599
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _In_ _Strict_type_match_ POOL_TYPE _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_opt_ ULONG _Out_ WDFLOOKASIDE * Lookaside
Definition: wdfmemory.h:414
#define VPB_MOUNTED
Definition: iotypes.h:1807
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtfsFileSystemControl().

◆ NtfsQueryMftZoneReservation()

static ULONG NtfsQueryMftZoneReservation ( VOID  )
static

Definition at line 172 of file fsctl.c.

173{
174 ULONG ZoneReservation = 1;
176
179 QueryTable[0].Name = L"NtfsMftZoneReservation";
180 QueryTable[0].EntryContext = &ZoneReservation;
181
183 L"FileSystem",
185 NULL,
186 NULL);
187
188 return ZoneReservation;
189}
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4231
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)

Referenced by NtfsGetVolumeData().

◆ NtfsUserFsRequest()

static NTSTATUS NtfsUserFsRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 978 of file fsctl.c.

980{
983 PDEVICE_EXTENSION DeviceExt;
984
985 DPRINT("NtfsUserFsRequest(%p, %p)\n", DeviceObject, Irp);
986
988 DeviceExt = DeviceObject->DeviceExtension;
989 switch (Stack->Parameters.FileSystemControl.FsControlCode)
990 {
995 //case FSCTL_GET_RETRIEVAL_POINTER_BASE:
997 //case FSCTL_LOOKUP_STREAM_FROM_CLUSTER:
999 case FSCTL_MOVE_FILE:
1003 //case FSCTL_SHRINK_VOLUME:
1006 DPRINT1("Unimplemented user request: %x\n", Stack->Parameters.FileSystemControl.FsControlCode);
1008 break;
1009
1010 case FSCTL_LOCK_VOLUME:
1011 Status = LockOrUnlockVolume(DeviceExt, Irp, TRUE);
1012 break;
1013
1015 Status = LockOrUnlockVolume(DeviceExt, Irp, FALSE);
1016 break;
1017
1019 Status = NtfsDismountVolume(DeviceExt, Irp);
1020 break;
1021
1023 Status = GetNfsVolumeData(DeviceExt, Irp);
1024 break;
1025
1027 Status = GetNtfsFileRecord(DeviceExt, Irp);
1028 break;
1029
1031 Status = GetVolumeBitmap(DeviceExt, Irp);
1032 break;
1033
1034 default:
1035 DPRINT("Invalid user request: %x\n", Stack->Parameters.FileSystemControl.FsControlCode);
1037 break;
1038 }
1039
1040 return Status;
1041}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
static NTSTATUS LockOrUnlockVolume(PDEVICE_EXTENSION DeviceExt, PIRP Irp, BOOLEAN Lock)
Definition: fsctl.c:857
static NTSTATUS GetVolumeBitmap(PDEVICE_EXTENSION DeviceExt, PIRP Irp)
Definition: fsctl.c:753
static NTSTATUS NtfsDismountVolume(PDEVICE_EXTENSION DeviceExt, PIRP Irp)
Definition: fsctl.c:930
static NTSTATUS GetNtfsFileRecord(PDEVICE_EXTENSION DeviceExt, PIRP Irp)
Definition: fsctl.c:686
static NTSTATUS GetNfsVolumeData(PDEVICE_EXTENSION DeviceExt, PIRP Irp)
Definition: fsctl.c:620
#define FSCTL_GET_NTFS_VOLUME_DATA
Definition: ntifs_ex.h:261
#define FSCTL_GET_NTFS_FILE_RECORD
Definition: ntifs_ex.h:262
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:751
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:750
#define FSCTL_MOVE_FILE
Definition: winioctl.h:752
#define FSCTL_WRITE_USN_CLOSE_RECORD
Definition: winioctl.h:177
#define FSCTL_READ_USN_JOURNAL
Definition: winioctl.h:164
#define FSCTL_DELETE_USN_JOURNAL
Definition: winioctl.h:180
#define FSCTL_MARK_HANDLE
Definition: winioctl.h:181
#define FSCTL_QUERY_USN_JOURNAL
Definition: winioctl.h:179
#define FSCTL_CREATE_USN_JOURNAL
Definition: winioctl.h:175
#define FSCTL_ENUM_USN_DATA
Definition: winioctl.h:162
#define FSCTL_EXTEND_VOLUME
Definition: winioctl.h:178
#define FSCTL_READ_FILE_USN_DATA
Definition: winioctl.h:176

Referenced by NtfsFileSystemControl().

◆ NtfsVerifyVolume()

static NTSTATUS NtfsVerifyVolume ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)
static

Definition at line 608 of file fsctl.c.

610{
613 DPRINT1("NtfsVerifyVolume() called\n");
614 return STATUS_WRONG_VOLUME;
615}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140

Referenced by NtfsFileSystemControl().