c3b273b1d5ec7c9ea206e1ffb83ee175fd185468
[reactos.git] / reactos / drivers / dd / ramdrv / ramdrv.c
1 #include <ntddk.h>
2 #include "ramdrv.h"
3 #include <debug.h>
4 #include "../../../lib/bzip2/bzlib.h"
5
6 NTSTATUS STDCALL RamdrvDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
7 PIRP Irp)
8 {
9 PRAMDRV_DEVICE_EXTENSION devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
10 PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( Irp );
11
12 if( Stk->Parameters.Read.ByteOffset.u.HighPart ||
13 Stk->Parameters.Read.ByteOffset.u.LowPart >= devext->Size )
14 {
15 Irp->IoStatus.Status = STATUS_END_OF_FILE;
16 Irp->IoStatus.Information = 0;
17 IoCompleteRequest( Irp, 0 );
18 return STATUS_END_OF_FILE;
19 }
20 if( (Stk->Parameters.Read.ByteOffset.u.LowPart + Stk->Parameters.Read.Length) > devext->Size )
21 Stk->Parameters.Read.Length = devext->Size - Stk->Parameters.Read.ByteOffset.u.LowPart;
22 if( Stk->MajorFunction == IRP_MJ_READ )
23 RtlCopyMemory( MmGetSystemAddressForMdl( Irp->MdlAddress ),
24 devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart,
25 Stk->Parameters.Read.Length );
26 else RtlCopyMemory( devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart,
27 MmGetSystemAddressForMdl( Irp->MdlAddress ),
28 Stk->Parameters.Read.Length );
29 Irp->IoStatus.Status = STATUS_SUCCESS;
30 Irp->IoStatus.Information = Stk->Parameters.Read.Length;
31 IoCompleteRequest( Irp, 0 );
32 return STATUS_SUCCESS;
33 }
34
35 NTSTATUS STDCALL RamdrvDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
36 PIRP Irp)
37 {
38 DPRINT("RamdrvDispatchOpenClose\n");
39 return STATUS_SUCCESS;
40 }
41
42 NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
43 IN PUNICODE_STRING RegistryPath)
44 {
45 UNICODE_STRING DeviceName;
46 NTSTATUS Status;
47 PDEVICE_OBJECT DeviceObject;
48 PRAMDRV_DEVICE_EXTENSION devext;
49 UNICODE_STRING LinkName;
50 HANDLE file;
51 OBJECT_ATTRIBUTES objattr;
52 IO_STATUS_BLOCK iosb;
53 LARGE_INTEGER allocsize;
54 HANDLE event;
55 void *tbuff;
56 unsigned int dstlen = 1024 * 1440;
57 FILE_STANDARD_INFORMATION finfo;
58 DWORD err;
59
60 DPRINT("Ramdisk driver\n");
61
62 /* Export other driver entry points... */
63 DriverObject->MajorFunction[IRP_MJ_CREATE] = RamdrvDispatchOpenClose;
64 DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamdrvDispatchOpenClose;
65 DriverObject->MajorFunction[IRP_MJ_READ] = RamdrvDispatchReadWrite;
66 DriverObject->MajorFunction[IRP_MJ_WRITE] = RamdrvDispatchReadWrite;
67 // DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
68 // RamdrvDispatchDeviceControl;
69
70
71 // create device and symbolic link
72 RtlInitUnicodeString( &DeviceName, L"\\Device\\Ramdisk" );
73 Status = IoCreateDevice( DriverObject,
74 sizeof( RAMDRV_DEVICE_EXTENSION ),
75 &DeviceName,
76 FILE_DEVICE_DISK,
77 0,
78 FALSE,
79 &DeviceObject );
80 if( !NT_SUCCESS( Status ) )
81 return Status;
82 DeviceObject->Flags |= DO_DIRECT_IO;
83 devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
84 devext->Size = 1440 * 1024;
85 devext->Buffer = ExAllocatePool( PagedPool, devext->Size );
86 if( !devext->Buffer )
87 {
88 Status = STATUS_INSUFFICIENT_RESOURCES;
89 goto cleandevice;
90 }
91 RtlInitUnicodeString( &LinkName, L"\\??\\Z:" );
92 IoCreateSymbolicLink( &LinkName, &DeviceName );
93
94 RtlInitUnicodeString( &LinkName, L"\\Device\\Floppy0\\ramdisk.bz2" );
95 InitializeObjectAttributes( &objattr,
96 &LinkName,
97 0,
98 0,
99 0 );
100 allocsize.u.LowPart = allocsize.u.HighPart = 0;
101
102 Status = NtOpenFile( &file,
103 GENERIC_READ,
104 &objattr,
105 &iosb,
106 FILE_SHARE_READ,
107 FILE_NO_INTERMEDIATE_BUFFERING );
108
109 if( !NT_SUCCESS( Status ) )
110 {
111 DPRINT( "Failed to open floppy\n" );
112 goto cleanbuffer;
113 }
114
115 InitializeObjectAttributes( &objattr,
116 0,
117 0,
118 0,
119 0 );
120 Status = NtCreateEvent( &event,
121 0,
122 &objattr,
123 TRUE,
124 FALSE );
125 if( !NT_SUCCESS( Status ) )
126 {
127 DPRINT( "Failed to create event\n" );
128 goto cleanfile;
129 }
130
131 Status = NtQueryInformationFile( file,
132 &iosb,
133 &finfo,
134 sizeof( finfo ),
135 FileStandardInformation );
136
137 if( !NT_SUCCESS( Status ) )
138 {
139 DPRINT1( "Failed to query file information\n" );
140 goto cleanevent;
141 }
142 tbuff = ExAllocatePool( PagedPool, finfo.EndOfFile.u.LowPart );
143 if( !tbuff )
144 {
145 DPRINT1( "Failed to allocate buffer of size %d\n", finfo.EndOfFile.u.LowPart );
146 Status = STATUS_INSUFFICIENT_RESOURCES;
147 goto cleanevent;
148 }
149
150 Status = NtReadFile( file,
151 event,
152 0,
153 0,
154 &iosb,
155 tbuff,
156 finfo.EndOfFile.u.LowPart,
157 &allocsize,
158 0 );
159
160 if( !NT_SUCCESS( Status ) )
161 {
162 DPRINT( "Failed to read floppy\n" );
163 goto cleantbuff;
164 }
165 Status = NtWaitForSingleObject( event, FALSE, 0 );
166 if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
167 {
168 DPRINT( "Failed to read floppy\n" );
169 goto cleantbuff;
170 }
171 DPRINT( "RAMDRV: Read in %d bytes, decompressing now\n", iosb.Information );
172 err = BZ2_bzBuffToBuffDecompress( devext->Buffer,
173 &dstlen,
174 tbuff,
175 iosb.Information,
176 1,
177 0 );
178 if( err == 0 )
179 DPRINT( "RAMDRV: Image Decompressed\n");
180 else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
181 ExFreePool( tbuff );
182 NtClose( file );
183 NtClose( event );
184 return STATUS_SUCCESS;
185
186 cleantbuff:
187 ExFreePool( tbuff );
188 cleanevent:
189 NtClose( event );
190 cleanfile:
191 NtClose( file );
192 cleanbuffer:
193 ExFreePool( devext->Buffer );
194
195 cleandevice:
196 IoDeleteDevice( DeviceObject );
197 for(;;);
198
199 return Status;
200 }
201