:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / minix / rw.c
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * FILE:             services/fs/minix/rw.c
5  * PURPOSE:          Minix FSD
6  * PROGRAMMER:       David Welch (welch@mcmail.com)
7  * UPDATE HISTORY: 
8  */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ddk/ntddk.h>
13 #include <string.h>
14 #include <ntos/minmax.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #include "minix.h"
20
21 /* FUNCTIONS ****************************************************************/
22
23 NTSTATUS STDCALL
24 MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
25 {
26    DPRINT("MinixWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
27    
28    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
29    Irp->IoStatus.Information = 0;
30    return(STATUS_UNSUCCESSFUL);
31 }
32
33 static NTSTATUS MinixReadFilePage(PDEVICE_OBJECT DeviceObject,
34                                   PMINIX_DEVICE_EXTENSION DeviceExt,
35                                   PMINIX_FSCONTEXT FsContext,
36                                   ULONG Offset,
37                                   PVOID* Buffer)
38 {
39    NTSTATUS Status;
40    ULONG i;
41    ULONG DiskOffset;
42
43    *Buffer = ExAllocatePool(NonPagedPool, 4096);
44
45    for (i=0; i<4; i++)
46      {
47         Status = MinixReadBlock(DeviceObject,
48                                 DeviceExt,
49                                 &FsContext->inode,
50                                 Offset + (i * BLOCKSIZE),
51                                 &DiskOffset);
52         MinixReadSector(DeviceObject,
53                         DiskOffset / BLOCKSIZE,
54                         (*Buffer) + (i * BLOCKSIZE));
55      }
56    return(STATUS_SUCCESS);
57 }
58
59 NTSTATUS STDCALL
60 MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
61 {
62    ULONG Length;
63    PVOID Buffer;
64    ULONG Offset;
65    ULONG CurrentOffset;
66    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
67    PFILE_OBJECT FileObject = Stack->FileObject;
68    MINIX_DEVICE_EXTENSION* DeviceExt = DeviceObject->DeviceExtension;
69    PMINIX_FSCONTEXT FsContext = (PMINIX_FSCONTEXT)FileObject->FsContext;
70    unsigned int i;
71    PVOID DiskBuffer;
72    
73    DPRINT("MinixRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
74    
75    Length = Stack->Parameters.Read.Length;
76    Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
77    Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
78    
79    DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
80    
81    CurrentOffset=Offset;
82    
83    DPRINT("inode->i_size %d\n",inode->i_size);
84    
85    if (Offset > FsContext->inode.i_size)
86      {
87         Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
88         Irp->IoStatus.Information = 0;
89         IoCompleteRequest(Irp,IO_NO_INCREMENT);
90         return(STATUS_UNSUCCESSFUL);
91      }
92    if ((Offset+Length) > FsContext->inode.i_size)
93      {
94         Length = FsContext->inode.i_size - Offset;
95      }
96    
97    if ((Offset%PAGE_SIZE)!=0)
98      {
99         CurrentOffset = Offset - (Offset%PAGE_SIZE);
100         
101         MinixReadFilePage(DeviceObject,
102                           DeviceExt,
103                           FsContext,
104                           CurrentOffset,
105                           &DiskBuffer);
106
107         memcpy(Buffer,
108                DiskBuffer+(Offset%PAGE_SIZE),
109                min(PAGE_SIZE - (Offset%PAGE_SIZE),Length));
110         
111         ExFreePool(DiskBuffer);
112         
113         DPRINT("(BLOCKSIZE - (Offset%BLOCKSIZE)) %d\n",
114                (BLOCKSIZE - (Offset%BLOCKSIZE)));
115         DPRINT("Length %d\n",Length);
116         CurrentOffset = CurrentOffset + PAGE_SIZE;
117         Buffer = Buffer + PAGE_SIZE - (Offset%PAGE_SIZE);
118         Length = Length - min(PAGE_SIZE - (Offset%PAGE_SIZE),Length);
119         DPRINT("CurrentOffset %d Buffer %x Length %d\n",CurrentOffset,Buffer,
120                Length);
121      }
122    for (i=0;i<(Length/PAGE_SIZE);i++)
123      {
124         CHECKPOINT;
125         
126         DPRINT("Length %d\n",Length);
127         
128         MinixReadFilePage(DeviceObject,
129                           DeviceExt,
130                           FsContext,
131                           CurrentOffset,
132                           &DiskBuffer);
133         memcpy(Buffer, DiskBuffer, PAGE_SIZE);
134         
135         ExFreePool(DiskBuffer);
136         
137         CurrentOffset = CurrentOffset + PAGE_SIZE;
138         Buffer = Buffer + PAGE_SIZE;
139      }
140    if ((Length%PAGE_SIZE) > 0)
141      {
142         CHECKPOINT;
143         
144         DPRINT("Length %x Buffer %x\n",(Length%PAGE_SIZE),Buffer);
145         
146         MinixReadFilePage(DeviceObject,
147                           DeviceExt,
148                           FsContext,
149                           CurrentOffset,
150                           &DiskBuffer);
151
152         memcpy(Buffer, DiskBuffer, (Length%PAGE_SIZE));
153
154         ExFreePool(DiskBuffer);
155
156      }
157    
158    Irp->IoStatus.Status = STATUS_SUCCESS;
159    Irp->IoStatus.Information = Length;
160    IoCompleteRequest(Irp,IO_NO_INCREMENT);
161    return(STATUS_SUCCESS);
162 }