xref: /reactos/drivers/filesystems/ntfs/blockdev.c (revision b819608e)
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 /* FUNCTIONS ****************************************************************/
34 
35 NTSTATUS
36 NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
37                 IN ULONG DiskSector,
38                 IN ULONG SectorCount,
39                 IN ULONG SectorSize,
40                 IN OUT PUCHAR Buffer,
41                 IN BOOLEAN Override)
42 {
43     PIO_STACK_LOCATION Stack;
44     IO_STATUS_BLOCK IoStatus;
45     LARGE_INTEGER Offset;
46     ULONG BlockSize;
47     KEVENT Event;
48     PIRP Irp;
49     NTSTATUS Status;
50 
51     KeInitializeEvent(&Event,
52                       NotificationEvent,
53                       FALSE);
54 
55     Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
56     BlockSize = SectorCount * SectorSize;
57 
58     DPRINT("NtfsReadSectors(DeviceObject %p, DiskSector %d, Buffer %p)\n",
59            DeviceObject, DiskSector, Buffer);
60     DPRINT("Offset %I64x BlockSize %ld\n",
61            Offset.QuadPart,
62            BlockSize);
63 
64     DPRINT("Building synchronous FSD Request...\n");
65     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
66                                        DeviceObject,
67                                        Buffer,
68                                        BlockSize,
69                                        &Offset,
70                                        &Event,
71                                        &IoStatus);
72     if (Irp == NULL)
73     {
74         DPRINT("IoBuildSynchronousFsdRequest failed\n");
75         return STATUS_INSUFFICIENT_RESOURCES;
76     }
77 
78     if (Override)
79     {
80         Stack = IoGetNextIrpStackLocation(Irp);
81         Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
82     }
83 
84     DPRINT("Calling IO Driver... with irp %p\n", Irp);
85     Status = IoCallDriver(DeviceObject, Irp);
86 
87     DPRINT("Waiting for IO Operation for %p\n", Irp);
88     if (Status == STATUS_PENDING)
89     {
90         DPRINT("Operation pending\n");
91         KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
92         DPRINT("Getting IO Status... for %p\n", Irp);
93         Status = IoStatus.Status;
94     }
95 
96     DPRINT("NtfsReadSectors() done (Status %x)\n", Status);
97 
98     return Status;
99 }
100 
101 
102 NTSTATUS
103 NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
104                     IN ULONG ControlCode,
105                     IN PVOID InputBuffer,
106                     IN ULONG InputBufferSize,
107                     IN OUT PVOID OutputBuffer,
108                     IN OUT PULONG OutputBufferSize,
109                     IN BOOLEAN Override)
110 {
111     PIO_STACK_LOCATION Stack;
112     IO_STATUS_BLOCK IoStatus;
113     KEVENT Event;
114     PIRP Irp;
115     NTSTATUS Status;
116 
117     KeInitializeEvent(&Event, NotificationEvent, FALSE);
118 
119     DPRINT("Building device I/O control request ...\n");
120     Irp = IoBuildDeviceIoControlRequest(ControlCode,
121                                         DeviceObject,
122                                         InputBuffer,
123                                         InputBufferSize,
124                                         OutputBuffer,
125                                         (OutputBufferSize) ? *OutputBufferSize : 0,
126                                         FALSE,
127                                         &Event,
128                                         &IoStatus);
129     if (Irp == NULL)
130     {
131         DPRINT("IoBuildDeviceIoControlRequest() failed\n");
132         return STATUS_INSUFFICIENT_RESOURCES;
133     }
134 
135     if (Override)
136     {
137         Stack = IoGetNextIrpStackLocation(Irp);
138         Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
139     }
140 
141     DPRINT("Calling IO Driver... with irp %p\n", Irp);
142     Status = IoCallDriver(DeviceObject, Irp);
143     if (Status == STATUS_PENDING)
144     {
145         KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
146         Status = IoStatus.Status;
147     }
148 
149     if (OutputBufferSize)
150     {
151         *OutputBufferSize = IoStatus.Information;
152     }
153 
154     return Status;
155 }
156 
157 /* EOF */
158