remove whitespace from end of lines
[reactos.git] / reactos / drivers / dd / ramdrv / ramdrv.c
1 #include <ntddk.h>
2 #include "ramdrv.h"
3 #include <debug.h>
4 #include <rosrtl/string.h>
5 #include "../../lib/bzip2/bzlib.h"
6
7 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 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 devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart,
67 Stk->Parameters.Read.Length );
68 else RtlCopyMemory( 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 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 = ROS_STRING_INITIALIZER(L"\\Device\\Ramdisk");
88 NTSTATUS Status;
89 PDEVICE_OBJECT DeviceObject;
90 PRAMDRV_DEVICE_EXTENSION devext;
91 UNICODE_STRING LinkName;
92 HANDLE file;
93 OBJECT_ATTRIBUTES objattr;
94 IO_STATUS_BLOCK iosb;
95 LARGE_INTEGER allocsize;
96 HANDLE event;
97 void *tbuff;
98 unsigned int dstlen = 1024 * 1440;
99 FILE_STANDARD_INFORMATION finfo;
100 DWORD err;
101
102 DPRINT("Ramdisk driver\n");
103
104 /* Export other driver entry points... */
105 DriverObject->MajorFunction[IRP_MJ_CREATE] = RamdrvDispatchOpenClose;
106 DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamdrvDispatchOpenClose;
107 DriverObject->MajorFunction[IRP_MJ_READ] = RamdrvDispatchReadWrite;
108 DriverObject->MajorFunction[IRP_MJ_WRITE] = RamdrvDispatchReadWrite;
109 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamdrvDispatchDeviceControl;
110
111
112 // create device and symbolic link
113 Status = IoCreateDevice( DriverObject,
114 sizeof( RAMDRV_DEVICE_EXTENSION ),
115 &DeviceName,
116 FILE_DEVICE_DISK,
117 0,
118 FALSE,
119 &DeviceObject );
120 if( !NT_SUCCESS( Status ) )
121 return Status;
122 DeviceObject->Flags |= DO_DIRECT_IO;
123 devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
124 devext->Size = 1440 * 1024;
125 devext->Buffer = ExAllocatePool( PagedPool, devext->Size );
126 if( !devext->Buffer )
127 {
128 Status = STATUS_INSUFFICIENT_RESOURCES;
129 goto cleandevice;
130 }
131 RtlRosInitUnicodeStringFromLiteral( &LinkName, L"\\??\\Z:" );
132 IoCreateSymbolicLink( &LinkName, &DeviceName );
133
134 RtlRosInitUnicodeStringFromLiteral( &LinkName, L"\\Device\\Floppy0\\ramdisk.bz2" );
135 InitializeObjectAttributes( &objattr,
136 &LinkName,
137 0,
138 0,
139 0 );
140 allocsize.u.LowPart = allocsize.u.HighPart = 0;
141
142 Status = ZwOpenFile( &file,
143 GENERIC_READ,
144 &objattr,
145 &iosb,
146 FILE_SHARE_READ,
147 FILE_NO_INTERMEDIATE_BUFFERING );
148
149 if( !NT_SUCCESS( Status ) )
150 {
151 DPRINT( "Failed to open floppy\n" );
152 goto cleanbuffer;
153 }
154
155 InitializeObjectAttributes( &objattr,
156 0,
157 0,
158 0,
159 0 );
160 Status = ZwCreateEvent( &event,
161 0,
162 &objattr,
163 NotificationEvent,
164 FALSE );
165 if( !NT_SUCCESS( Status ) )
166 {
167 DPRINT( "Failed to create event\n" );
168 goto cleanfile;
169 }
170
171 Status = ZwQueryInformationFile( file,
172 &iosb,
173 &finfo,
174 sizeof( finfo ),
175 FileStandardInformation );
176
177 if( !NT_SUCCESS( Status ) )
178 {
179 DPRINT1( "Failed to query file information\n" );
180 goto cleanevent;
181 }
182 tbuff = ExAllocatePool( PagedPool, finfo.EndOfFile.u.LowPart );
183 if( !tbuff )
184 {
185 DPRINT1( "Failed to allocate buffer of size %d\n", finfo.EndOfFile.u.LowPart );
186 Status = STATUS_INSUFFICIENT_RESOURCES;
187 goto cleanevent;
188 }
189
190 Status = ZwReadFile( file,
191 event,
192 0,
193 0,
194 &iosb,
195 tbuff,
196 finfo.EndOfFile.u.LowPart,
197 &allocsize,
198 0 );
199
200 if( !NT_SUCCESS( Status ) )
201 {
202 DPRINT( "Failed to read floppy\n" );
203 goto cleantbuff;
204 }
205 Status = ZwWaitForSingleObject( event, FALSE, 0 );
206 if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
207 {
208 DPRINT( "Failed to read floppy\n" );
209 goto cleantbuff;
210 }
211 DPRINT( "RAMDRV: Read in %d bytes, decompressing now\n", iosb.Information );
212 err = BZ2_bzBuffToBuffDecompress( devext->Buffer,
213 &dstlen,
214 tbuff,
215 iosb.Information,
216 1,
217 0 );
218 if( err == 0 )
219 {
220 DPRINT( "RAMDRV: Image Decompressed\n");
221 }
222 else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
223 ExFreePool( tbuff );
224 ZwClose( file );
225 ZwClose( event );
226 return STATUS_SUCCESS;
227
228 cleantbuff:
229 ExFreePool( tbuff );
230 cleanevent:
231 ZwClose( event );
232 cleanfile:
233 ZwClose( file );
234 cleanbuffer:
235 ExFreePool( devext->Buffer );
236
237 cleandevice:
238 IoDeleteDevice( DeviceObject );
239 for(;;);
240
241 return Status;
242 }
243