update for HEAD-2003091401
[reactos.git] / drivers / fs / ntfs / rw.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 ReactOS Team
4  *
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.
9  *
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.
14  *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$
20  *
21  * COPYRIGHT:        See COPYING in the top level directory
22  * PROJECT:          ReactOS kernel
23  * FILE:             services/fs/cdfs/rw.c
24  * PURPOSE:          CDROM (ISO 9660) filesystem driver
25  * PROGRAMMER:       Art Yerkes
26  * UPDATE HISTORY: 
27  */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32 #include <ntos/minmax.h>
33
34 //#define NDEBUG
35 #include <debug.h>
36
37 #include "ntfs.h"
38
39
40 /* GLOBALS *******************************************************************/
41
42 #define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
43 #define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
44
45
46 /* FUNCTIONS ****************************************************************/
47
48 static NTSTATUS
49 NtfsReadFile(PDEVICE_EXTENSION DeviceExt,
50              PFILE_OBJECT FileObject,
51              PUCHAR Buffer,
52              ULONG Length,
53              ULONG ReadOffset,
54              ULONG IrpFlags,
55              PULONG LengthRead)
56 /*
57  * FUNCTION: Reads data from a file
58  */
59 {
60 #if 0
61   NTSTATUS Status = STATUS_SUCCESS;
62   PUCHAR TempBuffer;
63   ULONG TempLength;
64   PCCB Ccb;
65   PFCB Fcb;
66
67   DPRINT("CdfsReadFile(ReadOffset %lu  Length %lu)\n", ReadOffset, Length);
68
69   *LengthRead = 0;
70
71   if (Length == 0)
72     return(STATUS_SUCCESS);
73
74   Ccb = (PCCB)FileObject->FsContext2;
75   Fcb = (PFCB)FileObject->FsContext;
76
77   if (ReadOffset >= Fcb->Entry.DataLengthL)
78     return(STATUS_END_OF_FILE);
79
80   DPRINT("Reading %d bytes at %d\n", Length, ReadOffset);
81
82   if (!(IrpFlags & (IRP_NOCACHE|IRP_PAGING_IO)))
83     {
84       LARGE_INTEGER FileOffset;
85       IO_STATUS_BLOCK IoStatus;
86
87       if (ReadOffset + Length > Fcb->Entry.DataLengthL)
88          Length = Fcb->Entry.DataLengthL - ReadOffset;
89       if (FileObject->PrivateCacheMap == NULL)
90       {
91           CcRosInitializeFileCache(FileObject, PAGE_SIZE);
92       }
93
94       FileOffset.QuadPart = (LONGLONG)ReadOffset;
95       CcCopyRead(FileObject,
96                  &FileOffset,
97                  Length,
98                  TRUE,
99                  Buffer,
100                  &IoStatus);
101       *LengthRead = IoStatus.Information;
102
103       return(IoStatus.Status);
104     }
105
106   if ((ReadOffset % BLOCKSIZE) != 0 || (Length % BLOCKSIZE) != 0)
107     {
108       return STATUS_INVALID_PARAMETER;
109     }
110   if (ReadOffset + Length > ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE))
111     Length = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE) - ReadOffset;
112
113   Status = CdfsReadSectors(DeviceExt->StorageDevice,
114                            Fcb->Entry.ExtentLocationL + (ReadOffset / BLOCKSIZE),
115                            Length / BLOCKSIZE,
116                            Buffer);
117   if (NT_SUCCESS(Status))
118     {
119       *LengthRead = Length;
120       if (Length + ReadOffset > Fcb->Entry.DataLengthL)
121       {
122         memset(Buffer + Fcb->Entry.DataLengthL - ReadOffset, 
123                0, Length + ReadOffset - Fcb->Entry.DataLengthL);
124       }
125     }
126
127   return(Status);
128 #else
129   *LengthRead = 0;
130   return STATUS_END_OF_FILE;
131 #endif
132 }
133
134
135 NTSTATUS STDCALL
136 NtfsRead(PDEVICE_OBJECT DeviceObject,
137          PIRP Irp)
138 {
139   PDEVICE_EXTENSION DeviceExt;
140   PIO_STACK_LOCATION Stack;
141   PFILE_OBJECT FileObject;
142   PVOID Buffer;
143   ULONG ReadLength;
144   LARGE_INTEGER ReadOffset;
145   ULONG ReturnedReadLength = 0;
146   NTSTATUS Status = STATUS_SUCCESS;
147
148   DPRINT("NtfsRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
149
150   DeviceExt = DeviceObject->DeviceExtension;
151   Stack = IoGetCurrentIrpStackLocation(Irp);
152   FileObject = Stack->FileObject;
153
154   ReadLength = Stack->Parameters.Read.Length;
155   ReadOffset = Stack->Parameters.Read.ByteOffset;
156   Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
157
158   Status = NtfsReadFile(DeviceExt,
159                         FileObject,
160                         Buffer,
161                         ReadLength,
162                         ReadOffset.u.LowPart,
163                         Irp->Flags,
164                         &ReturnedReadLength);
165
166 ByeBye:
167   if (NT_SUCCESS(Status))
168     {
169       if (FileObject->Flags & FO_SYNCHRONOUS_IO)
170         {
171           FileObject->CurrentByteOffset.QuadPart = 
172             ReadOffset.QuadPart + ReturnedReadLength;
173         }
174       Irp->IoStatus.Information = ReturnedReadLength;
175     }
176   else
177     {
178       Irp->IoStatus.Information = 0;
179     }
180
181   Irp->IoStatus.Status = Status;
182   IoCompleteRequest(Irp,IO_NO_INCREMENT);
183
184   return(Status);
185 }
186
187
188 NTSTATUS STDCALL
189 NtfsWrite(PDEVICE_OBJECT DeviceObject,
190           PIRP Irp)
191 {
192   DPRINT("NtfwWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
193
194   Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
195   Irp->IoStatus.Information = 0;
196   return(STATUS_NOT_SUPPORTED);
197 }
198
199 /* EOF */