3 * Copyright (C) 2002, 2014 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/rw.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMERS: Art Yerkes
24 * Pierre Schweitzer (pierre@reactos.org)
27 /* INCLUDES *****************************************************************/
35 /* FUNCTIONS ****************************************************************/
38 * FUNCTION: Reads data from a file
42 NtfsReadFile(PDEVICE_EXTENSION DeviceExt
,
43 PFILE_OBJECT FileObject
,
50 NTSTATUS Status
= STATUS_SUCCESS
;
52 PFILE_RECORD_HEADER FileRecord
;
53 PNTFS_ATTR_CONTEXT DataContext
;
58 BOOLEAN AllocatedBuffer
= FALSE
;
59 PCHAR ReadBuffer
= (PCHAR
)Buffer
;
61 DPRINT1("NtfsReadFile(%p, %p, %p, %u, %u, %x, %p)\n", DeviceExt
, FileObject
, Buffer
, Length
, ReadOffset
, IrpFlags
, LengthRead
);
67 DPRINT1("Null read!\n");
68 return STATUS_SUCCESS
;
71 Fcb
= (PNTFS_FCB
)FileObject
->FsContext
;
73 if (ReadOffset
>= Fcb
->Entry
.AllocatedSize
)
75 DPRINT1("Reading beyond file end!\n");
76 return STATUS_END_OF_FILE
;
80 if (ReadOffset
+ Length
> Fcb
->Entry
.AllocatedSize
)
81 ToRead
= Fcb
->Entry
.AllocatedSize
- ReadOffset
;
83 RealReadOffset
= ReadOffset
;
86 if ((ReadOffset
% DeviceExt
->NtfsInfo
.BytesPerSector
) != 0 || (ToRead
% DeviceExt
->NtfsInfo
.BytesPerSector
) != 0)
88 RealReadOffset
= ROUND_DOWN(ReadOffset
, DeviceExt
->NtfsInfo
.BytesPerSector
);
89 RealLength
= ROUND_UP(ToRead
, DeviceExt
->NtfsInfo
.BytesPerSector
);
91 ReadBuffer
= ExAllocatePoolWithTag(NonPagedPool
, RealLength
+ DeviceExt
->NtfsInfo
.BytesPerSector
, TAG_NTFS
);
92 if (ReadBuffer
== NULL
)
94 DPRINT1("Not enough memory!\n");
95 return STATUS_INSUFFICIENT_RESOURCES
;
97 AllocatedBuffer
= TRUE
;
100 FileRecord
= ExAllocatePoolWithTag(NonPagedPool
, DeviceExt
->NtfsInfo
.BytesPerFileRecord
, TAG_NTFS
);
101 if (FileRecord
== NULL
)
103 DPRINT1("Not enough memory!\n");
104 return STATUS_INSUFFICIENT_RESOURCES
;
107 Status
= ReadFileRecord(DeviceExt
, Fcb
->MFTIndex
, FileRecord
);
108 if (!NT_SUCCESS(Status
))
110 DPRINT1("Can't find record!\n");
111 ExFreePoolWithTag(FileRecord
, TAG_NTFS
);
115 Status
= FindAttribute(DeviceExt
, FileRecord
, AttributeData
, L
"", 0, &DataContext
);
116 if (!NT_SUCCESS(Status
))
118 DPRINT1("No data associated with file!\n");
119 ExFreePoolWithTag(FileRecord
, TAG_NTFS
);
123 DPRINT1("Effective read: %lu at %lu\n", RealLength
, RealReadOffset
);
124 RealLengthRead
= ReadAttribute(DeviceExt
, DataContext
, RealReadOffset
, (PCHAR
)ReadBuffer
, RealLength
);
125 if (RealLengthRead
!= RealLength
)
127 DPRINT1("Read failure!\n");
128 ReleaseAttributeContext(DataContext
);
129 ExFreePoolWithTag(FileRecord
, TAG_NTFS
);
132 ExFreePoolWithTag(ReadBuffer
, TAG_NTFS
);
137 ReleaseAttributeContext(DataContext
);
138 ExFreePoolWithTag(FileRecord
, TAG_NTFS
);
140 *LengthRead
= ToRead
;
142 DPRINT1("%lu got read\n", *LengthRead
);
146 RtlCopyMemory(Buffer
, ReadBuffer
+ (ReadOffset
- RealReadOffset
), ToRead
);
149 if (ToRead
!= Length
)
151 RtlZeroMemory(Buffer
+ ToRead
, Length
- ToRead
);
156 ExFreePoolWithTag(ReadBuffer
, TAG_NTFS
);
159 return STATUS_SUCCESS
;
165 NtfsFsdRead(PDEVICE_OBJECT DeviceObject
,
168 PDEVICE_EXTENSION DeviceExt
;
169 PIO_STACK_LOCATION Stack
;
170 PFILE_OBJECT FileObject
;
173 LARGE_INTEGER ReadOffset
;
174 ULONG ReturnedReadLength
= 0;
175 NTSTATUS Status
= STATUS_SUCCESS
;
177 DPRINT("NtfsRead(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
179 DeviceExt
= DeviceObject
->DeviceExtension
;
180 Stack
= IoGetCurrentIrpStackLocation(Irp
);
181 FileObject
= Stack
->FileObject
;
183 ReadLength
= Stack
->Parameters
.Read
.Length
;
184 ReadOffset
= Stack
->Parameters
.Read
.ByteOffset
;
185 Buffer
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
187 Status
= NtfsReadFile(DeviceExt
,
191 ReadOffset
.u
.LowPart
,
193 &ReturnedReadLength
);
194 if (NT_SUCCESS(Status
))
196 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
198 FileObject
->CurrentByteOffset
.QuadPart
=
199 ReadOffset
.QuadPart
+ ReturnedReadLength
;
202 Irp
->IoStatus
.Information
= ReturnedReadLength
;
206 Irp
->IoStatus
.Information
= 0;
209 Irp
->IoStatus
.Status
= Status
;
210 IoCompleteRequest(Irp
,IO_NO_INCREMENT
);
218 NtfsFsdWrite(PDEVICE_OBJECT DeviceObject
,
221 DPRINT("NtfwWrite(DeviceObject %x Irp %x)\n",DeviceObject
,Irp
);
223 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
224 Irp
->IoStatus
.Information
= 0;
225 return STATUS_NOT_SUPPORTED
;