Sync with trunk r58740.
[reactos.git] / drivers / filesystems / 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., 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 */