:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / fs_rec / 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/fs_rec/blockdev.c
24  * PURPOSE:          Filesystem recognizer 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 "fs_rec.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 NTSTATUS
41 FsRecReadSectors(IN PDEVICE_OBJECT DeviceObject,
42                  IN ULONG DiskSector,
43                  IN ULONG SectorCount,
44                  IN ULONG SectorSize,
45                  IN OUT PUCHAR Buffer)
46 {
47   PIO_STACK_LOCATION Stack;
48   IO_STATUS_BLOCK IoStatus;
49   LARGE_INTEGER Offset;
50   ULONG BlockSize;
51   PKEVENT Event;
52   PIRP Irp;
53   NTSTATUS Status;
54
55   Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
56   if (Event == NULL)
57     {
58       return(STATUS_INSUFFICIENT_RESOURCES);
59     }
60
61   KeInitializeEvent(Event,
62                     NotificationEvent,
63                     FALSE);
64
65   Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
66   BlockSize = SectorCount * SectorSize;
67
68   DPRINT("FsrecReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
69          DeviceObject, DiskSector, Buffer);
70   DPRINT("Offset %I64x BlockSize %ld\n",
71          Offset.QuadPart,
72          BlockSize);
73
74   DPRINT("Building synchronous FSD Request...\n");
75   Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
76                                      DeviceObject,
77                                      Buffer,
78                                      BlockSize,
79                                      &Offset,
80                                      Event,
81                                      &IoStatus);
82   if (Irp == NULL)
83     {
84       DPRINT("IoBuildSynchronousFsdRequest failed\n");
85       ExFreePool(Event);
86       return(STATUS_INSUFFICIENT_RESOURCES);
87     }
88
89   DPRINT("Calling IO Driver... with irp %x\n", Irp);
90   Status = IoCallDriver(DeviceObject, Irp);
91   if (Status == STATUS_PENDING)
92     {
93       DPRINT("Operation pending\n");
94       KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
95       Status = IoStatus.Status;
96     }
97
98   ExFreePool(Event);
99
100   return(STATUS_SUCCESS);
101 }
102
103
104 NTSTATUS
105 FsRecDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
106                      IN ULONG ControlCode,
107                      IN PVOID InputBuffer,
108                      IN ULONG InputBufferSize,
109                      IN OUT PVOID OutputBuffer,
110                      IN OUT PULONG OutputBufferSize)
111 {
112   ULONG BufferSize = 0;
113   PKEVENT Event;
114   PIRP Irp;
115   IO_STATUS_BLOCK IoStatus;
116   NTSTATUS Status;
117
118   if (OutputBufferSize != NULL)
119     {
120       BufferSize = *OutputBufferSize;
121     }
122
123   Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
124   if (Event == NULL)
125     {
126       return(STATUS_INSUFFICIENT_RESOURCES);
127     }
128
129   KeInitializeEvent(Event, NotificationEvent, FALSE);
130
131   DPRINT("Building device I/O control request ...\n");
132   Irp = IoBuildDeviceIoControlRequest(ControlCode,
133                                       DeviceObject,
134                                       InputBuffer,
135                                       InputBufferSize,
136                                       OutputBuffer,
137                                       BufferSize,
138                                       FALSE,
139                                       Event,
140                                       &IoStatus);
141   if (Irp == NULL)
142     {
143       DPRINT("IoBuildDeviceIoControlRequest() failed\n");
144       ExFreePool(Event);
145       return(STATUS_INSUFFICIENT_RESOURCES);
146     }
147
148   DPRINT("Calling IO Driver... with irp %x\n", Irp);
149   Status = IoCallDriver(DeviceObject, Irp);
150   if (Status == STATUS_PENDING)
151     {
152       KeWaitForSingleObject(Event, Suspended, KernelMode, FALSE, NULL);
153       Status = IoStatus.Status;
154     }
155
156   if (OutputBufferSize)
157     {
158       *OutputBufferSize = BufferSize;
159     }
160
161   ExFreePool(Event);
162
163   return(Status);
164 }
165
166 /* EOF */