:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / ntfs / blockdev.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/ntfs/blockdev.c
24  * PURPOSE:          NTFS filesystem driver
25  * PROGRAMMER:       Eric Kohl
26  */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 #include "ntfs.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 NTSTATUS
41 NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
42                 IN ULONG DiskSector,
43                 IN ULONG SectorCount,
44                 IN ULONG SectorSize,
45                 IN OUT PUCHAR Buffer)
46 {
47   IO_STATUS_BLOCK IoStatus;
48   LARGE_INTEGER Offset;
49   ULONG BlockSize;
50   KEVENT Event;
51   PIRP Irp;
52   NTSTATUS Status;
53
54   KeInitializeEvent(&Event,
55                     NotificationEvent,
56                     FALSE);
57
58   Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
59   BlockSize = SectorCount * SectorSize;
60
61   DPRINT("NtfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
62          DeviceObject, DiskSector, Buffer);
63   DPRINT("Offset %I64x BlockSize %ld\n",
64          Offset.QuadPart,
65          BlockSize);
66
67   DPRINT("Building synchronous FSD Request...\n");
68   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
69                                      DeviceObject,
70                                      Buffer,
71                                      BlockSize,
72                                      &Offset,
73                                      &Event,
74                                      &IoStatus);
75   if (Irp == NULL)
76     {
77       DPRINT("IoBuildSynchronousFsdRequest failed\n");
78       return(STATUS_INSUFFICIENT_RESOURCES);
79     }
80
81   DPRINT("Calling IO Driver... with irp %x\n", Irp);
82   Status = IoCallDriver(DeviceObject, Irp);
83
84   DPRINT("Waiting for IO Operation for %x\n", Irp);
85   if (Status == STATUS_PENDING)
86     {
87       DPRINT("Operation pending\n");
88       KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
89       DPRINT("Getting IO Status... for %x\n", Irp);
90       Status = IoStatus.Status;
91     }
92
93   if (!NT_SUCCESS(Status))
94     {
95       if (Status == STATUS_VERIFY_REQUIRED)
96         {
97           PDEVICE_OBJECT DeviceToVerify;
98           NTSTATUS NewStatus;
99
100           DPRINT1("STATUS_VERIFY_REQUIRED\n");
101           DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
102           IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
103
104           NewStatus = IoVerifyVolume(DeviceToVerify, FALSE);
105           DPRINT1("IoVerifyVolume() retuned (Status %lx)\n", NewStatus);
106         }
107
108       DPRINT("NtfsReadSectors() failed (Status %x)\n", Status);
109       DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
110              DeviceObject, DiskSector, Buffer,
111              Offset.QuadPart);
112       return(Status);
113     }
114
115   DPRINT("Block request succeeded for %x\n", Irp);
116
117   return(STATUS_SUCCESS);
118 }
119
120
121 NTSTATUS
122 NtfsReadRawSectors(IN PDEVICE_OBJECT DeviceObject,
123                    IN ULONG DiskSector,
124                    IN ULONG SectorCount,
125                    IN ULONG SectorSize,
126                    IN OUT PUCHAR Buffer)
127 {
128   PIO_STACK_LOCATION Stack;
129   IO_STATUS_BLOCK IoStatus;
130   LARGE_INTEGER Offset;
131   ULONG BlockSize;
132   KEVENT Event;
133   PIRP Irp;
134   NTSTATUS Status;
135
136   KeInitializeEvent(&Event,
137                     NotificationEvent,
138                     FALSE);
139
140   Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
141   BlockSize = SectorCount * SectorSize;
142
143   DPRINT("NtfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
144          DeviceObject, DiskSector, Buffer);
145   DPRINT("Offset %I64x BlockSize %ld\n",
146          Offset.QuadPart,
147          BlockSize);
148
149   DPRINT("Building synchronous FSD Request...\n");
150   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
151                                      DeviceObject,
152                                      Buffer,
153                                      BlockSize,
154                                      &Offset,
155                                      &Event,
156                                      &IoStatus);
157   if (Irp == NULL)
158     {
159       DPRINT("IoBuildSynchronousFsdRequest failed\n");
160       return(STATUS_INSUFFICIENT_RESOURCES);
161     }
162
163 //  Stack = IoGetCurrentIrpStackLocation(Irp);
164 //  Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
165
166   DPRINT("Calling IO Driver... with irp %x\n", Irp);
167   Status = IoCallDriver(DeviceObject, Irp);
168
169   DPRINT("Waiting for IO Operation for %x\n", Irp);
170   if (Status == STATUS_PENDING)
171     {
172       DPRINT("Operation pending\n");
173       KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
174       DPRINT("Getting IO Status... for %x\n", Irp);
175       Status = IoStatus.Status;
176     }
177
178   if (!NT_SUCCESS(Status))
179     {
180       DPRINT("NtfsReadSectors() failed (Status %x)\n", Status);
181       DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
182              DeviceObject, DiskSector, Buffer,
183              Offset.QuadPart);
184       return(Status);
185     }
186
187   DPRINT("Block request succeeded for %x\n", Irp);
188
189   return(STATUS_SUCCESS);
190 }
191
192
193 NTSTATUS
194 NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
195                     IN ULONG ControlCode,
196                     IN PVOID InputBuffer,
197                     IN ULONG InputBufferSize,
198                     IN OUT PVOID OutputBuffer,
199                     IN OUT PULONG OutputBufferSize)
200 {
201   ULONG BufferSize = 0;
202   PKEVENT Event;
203   PIRP Irp;
204   IO_STATUS_BLOCK IoStatus;
205   NTSTATUS Status;
206
207   if (OutputBufferSize != NULL)
208     {
209       BufferSize = *OutputBufferSize;
210     }
211
212   Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
213   if (Event == NULL)
214     {
215       return(STATUS_INSUFFICIENT_RESOURCES);
216     }
217
218   KeInitializeEvent(Event, NotificationEvent, FALSE);
219
220   DPRINT("Building device I/O control request ...\n");
221   Irp = IoBuildDeviceIoControlRequest(ControlCode,
222                                       DeviceObject,
223                                       InputBuffer,
224                                       InputBufferSize,
225                                       OutputBuffer,
226                                       BufferSize,
227                                       FALSE,
228                                       Event,
229                                       &IoStatus);
230   if (Irp == NULL)
231     {
232       DPRINT("IoBuildDeviceIoControlRequest() failed\n");
233       ExFreePool(Event);
234       return(STATUS_INSUFFICIENT_RESOURCES);
235     }
236
237   DPRINT("Calling IO Driver... with irp %x\n", Irp);
238   Status = IoCallDriver(DeviceObject, Irp);
239   if (Status == STATUS_PENDING)
240     {
241       KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
242       Status = IoStatus.Status;
243     }
244
245   if (OutputBufferSize)
246     {
247       *OutputBufferSize = BufferSize;
248     }
249
250   ExFreePool(Event);
251
252   return(Status);
253 }
254
255 /* EOF */