797924eca799a00545951eb1388348f53b852e66
[reactos.git] / rosapps / ramdrv / ramdrv.c
1 #include <ntddk.h>
2 #include <ntdddisk.h>
3 #include "ramdrv.h"
4 #include <debug.h>
5 #include "bzlib.h"
6
7 static NTSTATUS STDCALL RamdrvDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
8 PIRP Irp)
9 {
10 PIO_STACK_LOCATION IrpStack;
11 ULONG ControlCode, InputLength, OutputLength;
12 NTSTATUS Status;
13
14 DPRINT("RamdrvDispatchDeviceControl\n");
15
16 IrpStack = IoGetCurrentIrpStackLocation(Irp);
17 ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
18 InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
19 OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
20
21 switch (ControlCode)
22 {
23 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
24 if (OutputLength < sizeof(DISK_GEOMETRY))
25 {
26 Status = STATUS_INVALID_PARAMETER;
27 }
28 else
29 {
30 PDISK_GEOMETRY Geometry = Irp->AssociatedIrp.SystemBuffer;
31 Geometry->MediaType = F3_1Pt44_512;
32 Geometry->Cylinders.QuadPart = 80;
33 Geometry->TracksPerCylinder = 2 * 18;
34 Geometry->SectorsPerTrack = 18;
35 Geometry->BytesPerSector = 512;
36 Status = STATUS_SUCCESS;
37 Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
38 }
39 break;
40 default:
41 Status = STATUS_INVALID_DEVICE_REQUEST;
42 }
43 Irp->IoStatus.Status = Status;
44 IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
45 return Status;
46 }
47
48 static NTSTATUS STDCALL RamdrvDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
49 PIRP Irp)
50 {
51 PRAMDRV_DEVICE_EXTENSION devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
52 PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( Irp );
53
54 if( Stk->Parameters.Read.ByteOffset.u.HighPart ||
55 Stk->Parameters.Read.ByteOffset.u.LowPart >= devext->Size )
56 {
57 Irp->IoStatus.Status = STATUS_END_OF_FILE;
58 Irp->IoStatus.Information = 0;
59 IoCompleteRequest( Irp, 0 );
60 return STATUS_END_OF_FILE;
61 }
62 if( (Stk->Parameters.Read.ByteOffset.u.LowPart + Stk->Parameters.Read.Length) > devext->Size )
63 Stk->Parameters.Read.Length = devext->Size - Stk->Parameters.Read.ByteOffset.u.LowPart;
64 if( Stk->MajorFunction == IRP_MJ_READ )
65 RtlCopyMemory( MmGetSystemAddressForMdl( Irp->MdlAddress ),
66 (PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
67 Stk->Parameters.Read.Length );
68 else RtlCopyMemory( (PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
69 MmGetSystemAddressForMdl( Irp->MdlAddress ),
70 Stk->Parameters.Read.Length );
71 Irp->IoStatus.Status = STATUS_SUCCESS;
72 Irp->IoStatus.Information = Stk->Parameters.Read.Length;
73 IoCompleteRequest( Irp, 0 );
74 return STATUS_SUCCESS;
75 }
76
77 static NTSTATUS STDCALL RamdrvDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
78 PIRP Irp)
79 {
80 DPRINT("RamdrvDispatchOpenClose\n");
81 return STATUS_SUCCESS;
82 }
83
84 NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
85 IN PUNICODE_STRING RegistryPath)
86 {
87 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Ramdisk");
88 NTSTATUS Status;
89 PDEVICE_OBJECT DeviceObject;
90 PRAMDRV_DEVICE_EXTENSION devext;
91 UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\??\\Z:");
92 UNICODE_STRING ImageName = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\ramdisk.bz2");
93 HANDLE file;
94 OBJECT_ATTRIBUTES objattr;
95 IO_STATUS_BLOCK iosb;
96 LARGE_INTEGER allocsize;
97 HANDLE event;
98 void *tbuff;
99 unsigned int dstlen = 1024 * 1440;
100 FILE_STANDARD_INFORMATION finfo;
101 ULONG err;
102
103 DPRINT("Ramdisk driver\n");
104
105 /* Export other driver entry points... */
106 DriverObject->MajorFunction[IRP_MJ_CREATE] = RamdrvDispatchOpenClose;
107 DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamdrvDispatchOpenClose;
108 DriverObject->MajorFunction[IRP_MJ_READ] = RamdrvDispatchReadWrite;
109 DriverObject->MajorFunction[IRP_MJ_WRITE] = RamdrvDispatchReadWrite;
110 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamdrvDispatchDeviceControl;
111
112
113 // create device and symbolic link
114 Status = IoCreateDevice( DriverObject,
115 sizeof( RAMDRV_DEVICE_EXTENSION ),
116 &DeviceName,
117 FILE_DEVICE_DISK,
118 0,
119 FALSE,
120 &DeviceObject );
121 if( !NT_SUCCESS( Status ) )
122 return Status;
123 DeviceObject->Flags |= DO_DIRECT_IO;
124 devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
125 devext->Size = 1440 * 1024;
126 devext->Buffer = ExAllocatePool( PagedPool, devext->Size );
127 if( !devext->Buffer )
128 {
129 Status = STATUS_INSUFFICIENT_RESOURCES;
130 goto cleandevice;
131 }
132 IoCreateSymbolicLink( &LinkName, &DeviceName );
133
134 InitializeObjectAttributes( &objattr,
135 &ImageName,
136 0,
137 0,
138 0 );
139 allocsize.u.LowPart = allocsize.u.HighPart = 0;
140
141 Status = ZwOpenFile( &file,
142 GENERIC_READ,
143 &objattr,
144 &iosb,
145 FILE_SHARE_READ,
146 FILE_NO_INTERMEDIATE_BUFFERING );
147
148 if( !NT_SUCCESS( Status ) )
149 {
150 DPRINT( "Failed to open floppy\n" );
151 goto cleanbuffer;
152 }
153
154 InitializeObjectAttributes( &objattr,
155 0,
156 0,
157 0,
158 0 );
159 Status = ZwCreateEvent( &event,
160 0,
161 &objattr,
162 NotificationEvent,
163 FALSE );
164 if( !NT_SUCCESS( Status ) )
165 {
166 DPRINT( "Failed to create event\n" );
167 goto cleanfile;
168 }
169
170 Status = ZwQueryInformationFile( file,
171 &iosb,
172 &finfo,
173 sizeof( finfo ),
174 FileStandardInformation );
175
176 if( !NT_SUCCESS( Status ) )
177 {
178 DPRINT1( "Failed to query file information\n" );
179 goto cleanevent;
180 }
181 tbuff = ExAllocatePool( PagedPool, finfo.EndOfFile.u.LowPart );
182 if( !tbuff )
183 {
184 DPRINT1( "Failed to allocate buffer of size %d\n", finfo.EndOfFile.u.LowPart );
185 Status = STATUS_INSUFFICIENT_RESOURCES;
186 goto cleanevent;
187 }
188
189 Status = ZwReadFile( file,
190 event,
191 0,
192 0,
193 &iosb,
194 tbuff,
195 finfo.EndOfFile.u.LowPart,
196 &allocsize,
197 0 );
198
199 if( !NT_SUCCESS( Status ) )
200 {
201 DPRINT( "Failed to read floppy\n" );
202 goto cleantbuff;
203 }
204 Status = ZwWaitForSingleObject( event, FALSE, 0 );
205 if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
206 {
207 DPRINT( "Failed to read floppy\n" );
208 goto cleantbuff;
209 }
210 DPRINT( "RAMDRV: Read in %d bytes, decompressing now\n", iosb.Information );
211 err = BZ2_bzBuffToBuffDecompress( devext->Buffer,
212 &dstlen,
213 tbuff,
214 iosb.Information,
215 1,
216 0 );
217 if( err == 0 )
218 {
219 DPRINT( "RAMDRV: Image Decompressed\n");
220 }
221 else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
222 ExFreePool( tbuff );
223 ZwClose( file );
224 ZwClose( event );
225 return STATUS_SUCCESS;
226
227 cleantbuff:
228 ExFreePool( tbuff );
229 cleanevent:
230 ZwClose( event );
231 cleanfile:
232 ZwClose( file );
233 cleanbuffer:
234 ExFreePool( devext->Buffer );
235
236 cleandevice:
237 IoDeleteDevice( DeviceObject );
238 for(;;);
239
240 return Status;
241 }
242