mirror of
https://github.com/reactos/reactos.git
synced 2024-11-04 22:00:55 +00:00
243 lines
6.8 KiB
C
243 lines
6.8 KiB
C
|
#include <ntddk.h>
|
||
|
#include <ntdddisk.h>
|
||
|
#include "ramdrv.h"
|
||
|
#include <debug.h>
|
||
|
#include "bzlib.h"
|
||
|
|
||
|
static NTSTATUS STDCALL RamdrvDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
|
||
|
PIRP Irp)
|
||
|
{
|
||
|
PIO_STACK_LOCATION IrpStack;
|
||
|
ULONG ControlCode, InputLength, OutputLength;
|
||
|
NTSTATUS Status;
|
||
|
|
||
|
DPRINT("RamdrvDispatchDeviceControl\n");
|
||
|
|
||
|
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||
|
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
|
||
|
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
|
||
|
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
|
||
|
|
||
|
switch (ControlCode)
|
||
|
{
|
||
|
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||
|
if (OutputLength < sizeof(DISK_GEOMETRY))
|
||
|
{
|
||
|
Status = STATUS_INVALID_PARAMETER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PDISK_GEOMETRY Geometry = Irp->AssociatedIrp.SystemBuffer;
|
||
|
Geometry->MediaType = F3_1Pt44_512;
|
||
|
Geometry->Cylinders.QuadPart = 80;
|
||
|
Geometry->TracksPerCylinder = 2 * 18;
|
||
|
Geometry->SectorsPerTrack = 18;
|
||
|
Geometry->BytesPerSector = 512;
|
||
|
Status = STATUS_SUCCESS;
|
||
|
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||
|
}
|
||
|
Irp->IoStatus.Status = Status;
|
||
|
IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
static NTSTATUS STDCALL RamdrvDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
|
||
|
PIRP Irp)
|
||
|
{
|
||
|
PRAMDRV_DEVICE_EXTENSION devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||
|
PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( Irp );
|
||
|
|
||
|
if( Stk->Parameters.Read.ByteOffset.u.HighPart ||
|
||
|
Stk->Parameters.Read.ByteOffset.u.LowPart >= devext->Size )
|
||
|
{
|
||
|
Irp->IoStatus.Status = STATUS_END_OF_FILE;
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
IoCompleteRequest( Irp, 0 );
|
||
|
return STATUS_END_OF_FILE;
|
||
|
}
|
||
|
if( (Stk->Parameters.Read.ByteOffset.u.LowPart + Stk->Parameters.Read.Length) > devext->Size )
|
||
|
Stk->Parameters.Read.Length = devext->Size - Stk->Parameters.Read.ByteOffset.u.LowPart;
|
||
|
if( Stk->MajorFunction == IRP_MJ_READ )
|
||
|
RtlCopyMemory( MmGetSystemAddressForMdl( Irp->MdlAddress ),
|
||
|
(PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
|
||
|
Stk->Parameters.Read.Length );
|
||
|
else RtlCopyMemory( (PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
|
||
|
MmGetSystemAddressForMdl( Irp->MdlAddress ),
|
||
|
Stk->Parameters.Read.Length );
|
||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||
|
Irp->IoStatus.Information = Stk->Parameters.Read.Length;
|
||
|
IoCompleteRequest( Irp, 0 );
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
static NTSTATUS STDCALL RamdrvDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
|
||
|
PIRP Irp)
|
||
|
{
|
||
|
DPRINT("RamdrvDispatchOpenClose\n");
|
||
|
return STATUS_SUCCESS;
|
||
|
}
|
||
|
|
||
|
NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||
|
IN PUNICODE_STRING RegistryPath)
|
||
|
{
|
||
|
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Ramdisk");
|
||
|
NTSTATUS Status;
|
||
|
PDEVICE_OBJECT DeviceObject;
|
||
|
PRAMDRV_DEVICE_EXTENSION devext;
|
||
|
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\??\\Z:");
|
||
|
UNICODE_STRING ImageName = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\ramdisk.bz2");
|
||
|
HANDLE file;
|
||
|
OBJECT_ATTRIBUTES objattr;
|
||
|
IO_STATUS_BLOCK iosb;
|
||
|
LARGE_INTEGER allocsize;
|
||
|
HANDLE event;
|
||
|
void *tbuff;
|
||
|
unsigned int dstlen = 1024 * 1440;
|
||
|
FILE_STANDARD_INFORMATION finfo;
|
||
|
ULONG err;
|
||
|
|
||
|
DPRINT("Ramdisk driver\n");
|
||
|
|
||
|
/* Export other driver entry points... */
|
||
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = RamdrvDispatchOpenClose;
|
||
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamdrvDispatchOpenClose;
|
||
|
DriverObject->MajorFunction[IRP_MJ_READ] = RamdrvDispatchReadWrite;
|
||
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = RamdrvDispatchReadWrite;
|
||
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamdrvDispatchDeviceControl;
|
||
|
|
||
|
|
||
|
// create device and symbolic link
|
||
|
Status = IoCreateDevice( DriverObject,
|
||
|
sizeof( RAMDRV_DEVICE_EXTENSION ),
|
||
|
&DeviceName,
|
||
|
FILE_DEVICE_DISK,
|
||
|
0,
|
||
|
FALSE,
|
||
|
&DeviceObject );
|
||
|
if( !NT_SUCCESS( Status ) )
|
||
|
return Status;
|
||
|
DeviceObject->Flags |= DO_DIRECT_IO;
|
||
|
devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||
|
devext->Size = 1440 * 1024;
|
||
|
devext->Buffer = ExAllocatePool( PagedPool, devext->Size );
|
||
|
if( !devext->Buffer )
|
||
|
{
|
||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
goto cleandevice;
|
||
|
}
|
||
|
IoCreateSymbolicLink( &LinkName, &DeviceName );
|
||
|
|
||
|
InitializeObjectAttributes( &objattr,
|
||
|
&ImageName,
|
||
|
0,
|
||
|
0,
|
||
|
0 );
|
||
|
allocsize.u.LowPart = allocsize.u.HighPart = 0;
|
||
|
|
||
|
Status = ZwOpenFile( &file,
|
||
|
GENERIC_READ,
|
||
|
&objattr,
|
||
|
&iosb,
|
||
|
FILE_SHARE_READ,
|
||
|
FILE_NO_INTERMEDIATE_BUFFERING );
|
||
|
|
||
|
if( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
DPRINT( "Failed to open floppy\n" );
|
||
|
goto cleanbuffer;
|
||
|
}
|
||
|
|
||
|
InitializeObjectAttributes( &objattr,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0 );
|
||
|
Status = ZwCreateEvent( &event,
|
||
|
0,
|
||
|
&objattr,
|
||
|
NotificationEvent,
|
||
|
FALSE );
|
||
|
if( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
DPRINT( "Failed to create event\n" );
|
||
|
goto cleanfile;
|
||
|
}
|
||
|
|
||
|
Status = ZwQueryInformationFile( file,
|
||
|
&iosb,
|
||
|
&finfo,
|
||
|
sizeof( finfo ),
|
||
|
FileStandardInformation );
|
||
|
|
||
|
if( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
DPRINT1( "Failed to query file information\n" );
|
||
|
goto cleanevent;
|
||
|
}
|
||
|
tbuff = ExAllocatePool( PagedPool, finfo.EndOfFile.u.LowPart );
|
||
|
if( !tbuff )
|
||
|
{
|
||
|
DPRINT1( "Failed to allocate buffer of size %d\n", finfo.EndOfFile.u.LowPart );
|
||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||
|
goto cleanevent;
|
||
|
}
|
||
|
|
||
|
Status = ZwReadFile( file,
|
||
|
event,
|
||
|
0,
|
||
|
0,
|
||
|
&iosb,
|
||
|
tbuff,
|
||
|
finfo.EndOfFile.u.LowPart,
|
||
|
&allocsize,
|
||
|
0 );
|
||
|
|
||
|
if( !NT_SUCCESS( Status ) )
|
||
|
{
|
||
|
DPRINT( "Failed to read floppy\n" );
|
||
|
goto cleantbuff;
|
||
|
}
|
||
|
Status = ZwWaitForSingleObject( event, FALSE, 0 );
|
||
|
if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
|
||
|
{
|
||
|
DPRINT( "Failed to read floppy\n" );
|
||
|
goto cleantbuff;
|
||
|
}
|
||
|
DPRINT( "RAMDRV: Read in %d bytes, decompressing now\n", iosb.Information );
|
||
|
err = BZ2_bzBuffToBuffDecompress( devext->Buffer,
|
||
|
&dstlen,
|
||
|
tbuff,
|
||
|
iosb.Information,
|
||
|
1,
|
||
|
0 );
|
||
|
if( err == 0 )
|
||
|
{
|
||
|
DPRINT( "RAMDRV: Image Decompressed\n");
|
||
|
}
|
||
|
else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
|
||
|
ExFreePool( tbuff );
|
||
|
ZwClose( file );
|
||
|
ZwClose( event );
|
||
|
return STATUS_SUCCESS;
|
||
|
|
||
|
cleantbuff:
|
||
|
ExFreePool( tbuff );
|
||
|
cleanevent:
|
||
|
ZwClose( event );
|
||
|
cleanfile:
|
||
|
ZwClose( file );
|
||
|
cleanbuffer:
|
||
|
ExFreePool( devext->Buffer );
|
||
|
|
||
|
cleandevice:
|
||
|
IoDeleteDevice( DeviceObject );
|
||
|
for(;;);
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|