⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ramdisk.c

📁 这个例程源码演示了在WINDOWS 2000下
💻 C
📖 第 1 页 / 共 3 页
字号:
            DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("Output buffer too small... \n" ) );
            status = STATUS_BUFFER_TOO_SMALL;       // Inform the caller we need bigger buffer
            information = sizeof(PARTITION_INFORMATION);
        } else {
            PPARTITION_INFORMATION outputBuffer;
            PBOOT_SECTOR    bootSector = (PBOOT_SECTOR) devExt->DiskImage;

            outputBuffer = ( PPARTITION_INFORMATION )Irp->AssociatedIrp.SystemBuffer;

            outputBuffer->PartitionType = 
                (bootSector->bsFileSystemType[4] == '6') ? PARTITION_FAT_16 : PARTITION_FAT_12;

            outputBuffer->BootIndicator       = FALSE;
            outputBuffer->RecognizedPartition = TRUE;
            outputBuffer->RewritePartition    = FALSE;
            outputBuffer->StartingOffset      = RtlConvertUlongToLargeInteger(0);
            outputBuffer->PartitionLength     = RtlConvertUlongToLargeInteger(devExt->DiskRegInfo.DiskSize);
            outputBuffer->HiddenSectors       = (ULONG) (1L);
            outputBuffer->PartitionNumber     = (ULONG) (-1L);

            status = STATUS_SUCCESS;
            information = sizeof( PARTITION_INFORMATION );
        }

        break;
    }                                        

    case IOCTL_DISK_GET_DRIVE_GEOMETRY: {

        DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("IOCTL_DISK_GET_DRIVE_GEOMETRY \n" ) );
        //
        // Return the drive geometry for the ram disk. Note that
        // we return values which were made up to suit the disk size.
        //

        if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
            sizeof( DISK_GEOMETRY ) )
        {
            //
            // Instead of returning STATUS_INVALID_PARAMETER, we will return
            // STATUS_BUFFER_TOO_SMALL and the required buffer size. 
            // So that the called will send a bigger buffer
            //
            status = STATUS_BUFFER_TOO_SMALL;       // Inform the caller we need bigger buffer
            information = sizeof(PARTITION_INFORMATION);
        }
        else
        {
            PDISK_GEOMETRY outputBuffer;

            outputBuffer = ( PDISK_GEOMETRY ) Irp->AssociatedIrp.SystemBuffer;
            RtlCopyMemory( outputBuffer, &(devExt->DiskGeometry), sizeof(DISK_GEOMETRY) );
            status = STATUS_SUCCESS;
            information = sizeof( DISK_GEOMETRY );
        }
        break;
    }

    case IOCTL_DISK_CHECK_VERIFY: {

        DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("IOCTL_DISK_CHECK_VERIFY \n" ) );
        //
        // Return status success
        //
        status = STATUS_SUCCESS;
        break;
    }                                        

    case IOCTL_DISK_IS_WRITABLE: {

        DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("IOCTL_DISK_IS_WRITABLE \n" ) );
        //
        // Return status success
        //
        status = STATUS_SUCCESS;
        break;
    }                                        

    default: {
        //
        // Received not supported IOCTLs, fail them
        DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("Unknown IOCTL command %X\n", command ) );
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    }   // end switch

    COMPLETE_REQUEST( Irp, status, information );
    IoReleaseRemoveLock(&devExt->RemoveLock, Irp);

    DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_VERBOSE, ("IOCtl- OUT \n" ) );
    return status;
}   // End of RamDiskIOCtl()



NTSTATUS
RamDiskReadWrite(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    This routine is called by the I/O system to read or write to a
    device that we control. It can also be called by
    RamDiskDispatchDeviceControl() to do a VERIFY.

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 based on the request

--*/

{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    ULONG               information = 0;
    PUCHAR              currentAddress;

    PDEVICE_EXTENSION   devExt = DeviceObject->DeviceExtension;
    DBGPRINT( DBG_COMP_READ, DBG_LEVEL_VERBOSE, ("ReadWrite - IN \n" ) );

    if ( devExt->DevState != WORKING ) {
        //
        // Device is not yet started or being removed, reject any IO request
        // TODO: Queue the IRPs

        DBGPRINT( DBG_COMP_READ, DBG_LEVEL_WARN, ("Device not ready\n" ) );
        status = STATUS_INVALID_DEVICE_STATE;
        COMPLETE_REQUEST( Irp, status, information );
    }
    status = IoAcquireRemoveLock(&devExt->RemoveLock, Irp);
    if (!NT_SUCCESS(status)) {
        DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_ERROR, ("Acquire RemoveLock failed\n" ) );
        COMPLETE_REQUEST( Irp, status, 0 );
        return status;
    }

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    //
    // Check for invalid parameters.  It is an error for the starting offset
    // + length to go past the end of the buffer, or for the length to
    // not be a proper multiple of the sector size.
    //
    // Others are possible, but we don't check them since we trust the
    // file system
    //

    if (RtlLargeIntegerGreaterThan(
            RtlLargeIntegerAdd( 
                irpStack->Parameters.Read.ByteOffset,
                RtlConvertUlongToLargeInteger(irpStack->Parameters.Read.Length)),
            RtlConvertUlongToLargeInteger(devExt->DiskRegInfo.DiskSize)) ||
        (irpStack->Parameters.Read.Length & (devExt->DiskGeometry.BytesPerSector - 1))) {
        //
        // Do not give an I/O boost for parameter errors.
        //
        DBGPRINT( DBG_COMP_READ, DBG_LEVEL_ERROR, 
            (
                "Error invalid parameter\n"
                "ByteOffset: %x\n"
                "Length: %d\n"
                "Operation: %x\n",
                irpStack->Parameters.Read.ByteOffset,
                irpStack->Parameters.Read.Length,
                irpStack->MajorFunction
            ));

        status = STATUS_INVALID_PARAMETER;
        COMPLETE_REQUEST( Irp, status, information );
        IoReleaseRemoveLock(&devExt->RemoveLock, Irp);
        return status;
    }

    //
    // Get a system-space pointer to the user's buffer.  A system
    // address must be used because we may already have left the
    // original caller's address space.
    //

    ASSERT ( Irp->MdlAddress != NULL );
    currentAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );

    //
    // The mapping request can fail if system is very low on resources.
    // Check for NULL and return approriate error status if the mapping failed
    //

    if ( currentAddress == NULL ) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        COMPLETE_REQUEST( Irp, status, information );
        IoReleaseRemoveLock(&devExt->RemoveLock, Irp);
        DBGPRINT( DBG_COMP_READ, DBG_LEVEL_ERROR, ("Unable to get the system-space virtual address\n" ) );
        return status;
    }

    DBGPRINT( DBG_COMP_READ, DBG_LEVEL_VERBOSE,
        (
            "Irp of Request: %x\n"
            "Vmem Address of Transfer: %x - %x\n"
            "Length of Transfer: %d\n"
            "Operation: %x\n"
            "Starting ByteOffset: %x\n",
            Irp,
            currentAddress,
            ((PUCHAR)currentAddress) + irpStack->Parameters.Read.Length,
            irpStack->Parameters.Read.Length,
            irpStack->MajorFunction,
            irpStack->Parameters.Read.ByteOffset.LowPart
        ));

    information = irpStack->Parameters.Read.Length;

    switch (irpStack->MajorFunction) {

    case IRP_MJ_READ:
        RtlMoveMemory(
            currentAddress,
            devExt->DiskImage + irpStack->Parameters.Read.ByteOffset.LowPart,
            irpStack->Parameters.Read.Length);
        break;

    case IRP_MJ_WRITE:
        RtlMoveMemory(
            devExt->DiskImage + irpStack->Parameters.Read.ByteOffset.LowPart,
            currentAddress, irpStack->Parameters.Read.Length);
        break;

    default:
        information = 0;
        break;
    }

    status = STATUS_SUCCESS;
    COMPLETE_REQUEST( Irp, status, information );
    IoReleaseRemoveLock(&devExt->RemoveLock, Irp);

    DBGPRINT( DBG_COMP_READ, DBG_LEVEL_VERBOSE, ("ReadWrite - OUT \n" ) );
    return status;
}   // End of RamDiskReadWrite()

#if DBG
                       
VOID
RamDiskQueryDebugRegParameters(
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine is called from the DriverEntry to get the debug
    parameters from the registry. If the registry query fails, then
    default values are used.

Arguments:

    RegistryPath    - Points the service path to get the registry parameters

Return Value:

    None

--*/
{

    RTL_QUERY_REGISTRY_TABLE    rtlQueryRegTbl[ 4 + 1 ];  // Need 1 for NULL
    NTSTATUS                    status;
    DEBUG_INFO                  defDebugRegInfo;

    PAGED_CODE();

    DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("QueryDebugRegParameters\n" ) );
    ASSERT( RegistryPath->Buffer != NULL );

    // Set the default values

    defDebugRegInfo.BreakOnEntry      = DEFAULT_BREAK_ON_ENTRY;
    defDebugRegInfo.DebugLevel        = DEFAULT_DEBUG_LEVEL;
    defDebugRegInfo.DebugComp         = DEFAULT_DEBUG_COMP;

    RtlZeroMemory( rtlQueryRegTbl, sizeof(rtlQueryRegTbl) );

    //
    // Setup the query table
    //

    rtlQueryRegTbl[0].Flags         = RTL_QUERY_REGISTRY_SUBKEY;
    rtlQueryRegTbl[0].Name          = L"Parameters";
    rtlQueryRegTbl[0].EntryContext  = NULL;
    rtlQueryRegTbl[0].DefaultType   = (ULONG)NULL;
    rtlQueryRegTbl[0].DefaultData   = NULL;
    rtlQueryRegTbl[0].DefaultLength = (ULONG)NULL;

    //
    // Debug paramters
    //

    rtlQueryRegTbl[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    rtlQueryRegTbl[1].Name          = L"BreakOnEntry";
    rtlQueryRegTbl[1].EntryContext  = &BreakOnEntry;
    rtlQueryRegTbl[1].DefaultType   = REG_DWORD;
    rtlQueryRegTbl[1].DefaultData   = &defDebugRegInfo.BreakOnEntry;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -