|
|
/*++
Copyright (c) 1991-1998 Microsoft Corporation
Module Name:
SFFDISK (Small Form Factor Disk)
Abstract:
Author:
Neil Sandlin (neilsa) 26-Apr-99
Environment:
Kernel mode only.
--*/ #include "pch.h"
//
// Internal References
//
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath );
VOID SffDiskUnload( IN PDRIVER_OBJECT DriverObject );
NTSTATUS SffDiskCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUS SffDiskReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,SffDiskCreateClose)
#pragma alloc_text(PAGE,SffDiskReadWrite)
#endif
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
/*++
Routine Description:
This routine is the driver's entry point, called by the I/O system to load the driver. The driver's entry points are initialized and a mutex to control paging is initialized.
In DBG mode, this routine also examines the registry for special debug parameters.
Arguments:
DriverObject - a pointer to the object that represents this device driver.
RegistryPath - a pointer to this driver's key in the Services tree.
Return Value:
STATUS_SUCCESS unless we can't allocate a mutex.
--*/
{ NTSTATUS ntStatus = STATUS_SUCCESS;
SffDiskDump(SFFDISKSHOW, ("SffDisk: DriverEntry\n") );
//
// Initialize the driver object with this driver's entry points.
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = SffDiskCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = SffDiskCreateClose; DriverObject->MajorFunction[IRP_MJ_READ] = SffDiskReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = SffDiskReadWrite; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SffDiskDeviceControl; DriverObject->MajorFunction[IRP_MJ_PNP] = SffDiskPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = SffDiskPower;
DriverObject->DriverUnload = SffDiskUnload;
DriverObject->DriverExtension->AddDevice = SffDiskAddDevice; return ntStatus; }
VOID SffDiskUnload( IN PDRIVER_OBJECT DriverObject ) /*++
Routine Description:
Unload the driver from the system. The paging mutex is freed before final unload.
Arguments:
DriverObject - a pointer to the object that represents this device driver.
Return Value: none
--*/
{ SffDiskDump( SFFDISKSHOW, ("SffDiskUnload:\n"));
//
// The device object(s) should all be gone by now.
//
ASSERT( DriverObject->DeviceObject == NULL );
return; }
NTSTATUS SffDiskCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
/*++
Routine Description:
This routine is called only rarely by the I/O system; it's mainly for layered drivers to call. All it does is complete the IRP successfully.
Arguments:
DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
Irp - a pointer to the I/O Request Packet for this request.
Return Value:
Always returns STATUS_SUCCESS, since this is a null operation.
--*/
{ UNREFERENCED_PARAMETER( DeviceObject );
//
// Null operation. Do not give an I/O boost since
// no I/O was actually done. IoStatus.Information should be
// FILE_OPENED for an open; it's undefined for a close.
//
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = FILE_OPENED;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS; }
NTSTATUS SffDiskReadWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
/*++
Routine Description:
This routine handles read/write irps for the memory card. It validates parameters and calls SffDiskReadWrite to do the real work.
Arguments:
DeviceObject - a pointer to the object that represents the device that I/O is to be done on.
Irp - a pointer to the I/O Request Packet for this request.
Return Value:
STATUS_SUCCESS if the packet was successfully read or written; the appropriate error is propogated otherwise.
--*/
{ NTSTATUS status = STATUS_SUCCESS; PSFFDISK_EXTENSION sffdiskExtension = DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); SffDiskDump(SFFDISKRW,("SffDisk: DO %.8x %s offset %.8x, buffer %.8x, len %x\n", sffdiskExtension->DeviceObject, (irpSp->MajorFunction == IRP_MJ_WRITE) ?"WRITE":"READ", irpSp->Parameters.Read.ByteOffset.LowPart, MmGetSystemAddressForMdl(Irp->MdlAddress), irpSp->Parameters.Read.Length));
//
// If the device is not active (not started yet or removed) we will
// just fail this request outright.
//
if ( sffdiskExtension->IsRemoved || !sffdiskExtension->IsStarted) { if ( sffdiskExtension->IsRemoved) { status = STATUS_DELETE_PENDING; } else { status = STATUS_UNSUCCESSFUL; } goto ReadWriteComplete; } if (((irpSp->Parameters.Read.ByteOffset.LowPart + irpSp->Parameters.Read.Length) > sffdiskExtension->ByteCapacity) || (irpSp->Parameters.Read.ByteOffset.HighPart != 0)) { status = STATUS_INVALID_PARAMETER; goto ReadWriteComplete; } //
// verify that user is really expecting some I/O operation to
// occur.
//
if (!irpSp->Parameters.Read.Length) { //
// Complete this zero length request with no boost.
//
Irp->IoStatus.Status = STATUS_SUCCESS; goto ReadWriteComplete; } if ((DeviceObject->Flags & DO_VERIFY_VOLUME) && !(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME)) { //
// The disk changed, and we set this bit. Fail
// all current IRPs for this device; when all are
// returned, the file system will clear
// DO_VERIFY_VOLUME.
//
status = STATUS_VERIFY_REQUIRED; goto ReadWriteComplete; } //
// Do the operation
//
if (irpSp->MajorFunction == IRP_MJ_WRITE) { status = (*(sffdiskExtension->FunctionBlock->WriteProc))(sffdiskExtension, Irp); } else { status = (*(sffdiskExtension->FunctionBlock->ReadProc))(sffdiskExtension, Irp); }
if (!NT_SUCCESS(status)) { SffDiskDump(SFFDISKFAIL,("SffDisk: Read/Write Error! %.8x\n", status));
//
// Retry the operation
//
if (irpSp->MajorFunction == IRP_MJ_WRITE) { status = (*(sffdiskExtension->FunctionBlock->WriteProc))(sffdiskExtension, Irp); } else { status = (*(sffdiskExtension->FunctionBlock->ReadProc))(sffdiskExtension, Irp); } SffDiskDump(SFFDISKFAIL,("SffDisk: status after retry %.8x\n", status)); } ReadWriteComplete:
if (NT_SUCCESS(status)) { Irp->IoStatus.Information = irpSp->Parameters.Read.Length; } else { Irp->IoStatus.Information = 0; }
SffDiskDump(SFFDISKRW,("SffDisk: DO %.8x RW Irp complete %.8x %.8x\n", sffdiskExtension->DeviceObject, status, Irp->IoStatus.Information));
Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
|