xref: /reactos/drivers/filesystems/ntfs/blockdev.c (revision 29fa274d)
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * COPYRIGHT:        See COPYING in the top level directory
20  * PROJECT:          ReactOS kernel
21  * FILE:             drivers/filesystem/ntfs/blockdev.c
22  * PURPOSE:          NTFS filesystem driver
23  * PROGRAMMER:       Eric Kohl
24  */
25 
26 /* INCLUDES *****************************************************************/
27 
28 #include "ntfs.h"
29 
30 #define NDEBUG
31 #include <debug.h>
32 
33 /* GLOBALS *****************************************************************/
34 
35 
36 /* FUNCTIONS ****************************************************************/
37 
38 NTSTATUS
39 NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
40 		IN ULONG DiskSector,
41 		IN ULONG SectorCount,
42 		IN ULONG SectorSize,
43 		IN OUT PUCHAR Buffer,
44 		IN BOOLEAN Override)
45 {
46   PIO_STACK_LOCATION Stack;
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 %p, DiskSector %d, Buffer %p)\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   if (Override)
82     {
83       Stack = IoGetNextIrpStackLocation(Irp);
84       Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
85     }
86 
87   DPRINT("Calling IO Driver... with irp %p\n", Irp);
88   Status = IoCallDriver(DeviceObject, Irp);
89 
90   DPRINT("Waiting for IO Operation for %p\n", Irp);
91   if (Status == STATUS_PENDING)
92     {
93       DPRINT("Operation pending\n");
94       KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
95       DPRINT("Getting IO Status... for %p\n", Irp);
96       Status = IoStatus.Status;
97     }
98 
99   DPRINT("NtfsReadSectors() done (Status %x)\n", Status);
100 
101   return Status;
102 }
103 
104 
105 NTSTATUS
106 NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
107 		    IN ULONG ControlCode,
108 		    IN PVOID InputBuffer,
109 		    IN ULONG InputBufferSize,
110 		    IN OUT PVOID OutputBuffer,
111 		    IN OUT PULONG OutputBufferSize,
112 		    IN BOOLEAN Override)
113 {
114   PIO_STACK_LOCATION Stack;
115   IO_STATUS_BLOCK IoStatus;
116   KEVENT Event;
117   PIRP Irp;
118   NTSTATUS Status;
119 
120   KeInitializeEvent(&Event, NotificationEvent, FALSE);
121 
122   DPRINT("Building device I/O control request ...\n");
123   Irp = IoBuildDeviceIoControlRequest(ControlCode,
124 				      DeviceObject,
125 				      InputBuffer,
126 				      InputBufferSize,
127 				      OutputBuffer,
128 				      (OutputBufferSize) ? *OutputBufferSize : 0,
129 				      FALSE,
130 				      &Event,
131 				      &IoStatus);
132   if (Irp == NULL)
133     {
134       DPRINT("IoBuildDeviceIoControlRequest() failed\n");
135       return STATUS_INSUFFICIENT_RESOURCES;
136     }
137 
138   if (Override)
139     {
140       Stack = IoGetNextIrpStackLocation(Irp);
141       Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
142     }
143 
144   DPRINT("Calling IO Driver... with irp %p\n", Irp);
145   Status = IoCallDriver(DeviceObject, Irp);
146   if (Status == STATUS_PENDING)
147     {
148       KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
149       Status = IoStatus.Status;
150     }
151 
152   if (OutputBufferSize)
153     {
154       *OutputBufferSize = IoStatus.Information;
155     }
156 
157   return Status;
158 }
159 
160 /* EOF */
161