📄 ramdisk.c
字号:
/*++
Copyright (c) 1990-2000 Microsoft Corporation, All Rights Reserved
Module Name:
Ramdisk.c
Abstract:
This is the Ramdisk sample driver.
Author:
Robert Nelson (RobertN) 10-Mar-1993.
Environment:
Kernel mode only.
Notes:
If the device is not ready, queue the I/O IRPs instead of rejecting
Revision History:
Added the IOCTL_DISK_GET_PARTITION_INFO query to make it work with NTFS
driver loaded (thanks Robert Vierthaler (RobertVi)).
Raju Ramanathan (Rajuram)
Converted the sample driver to Windows 2000 02/22/2000
Code cleaning 04/19/2000
--*/
#include "ramdisk.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text( INIT, DriverEntry )
#pragma alloc_text( PAGE, RamDiskCreateClose)
#pragma alloc_text( PAGE, RamDiskUnload)
#pragma alloc_text( PAGE, RamDiskQueryDiskRegParameters )
#pragma alloc_text( PAGE, RamDiskFormatDisk )
#pragma alloc_text( PAGE, RamDiskAddDevice )
#pragma alloc_text( PAGE, RamDiskDispatchPnp )
#pragma alloc_text( PAGE, RamDiskDispatchPower )
#pragma alloc_text( PAGE, RamDiskDispatchSystemControl )
#pragma alloc_text( PAGE, RamDiskRemoveDevice )
#pragma alloc_text( PAGE, GetPnpIrpName )
#if DBG
#pragma alloc_text( PAGE, RamDiskQueryDebugRegParameters )
#endif
#endif // ALLOC_PRAGMA
#if DBG
ULONG BreakOnEntry = FALSE;
ULONG DbgLevel = DBG_LEVEL_ERROR;
ULONG DbgComp = DBG_COMP_ALL;
// To disable selected components
//ULONG DbgComp = DBG_COMP_ALL & ~DBG_COMP_PNP;
#endif // DBG
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
RegistryPath - pointer to a unicode string representing the path
to driver-specific key in the registry
Return Value:
STATUS_SUCCESS if successful.
--*/
{
PRAMDISK_DRIVER_EXTENSION driverExtension;
NTSTATUS status;
#if DBG
CHAR VersionHerald[] = "Windows 2000 Ramdisk Driver - Version %s built on %s\n";
CHAR VersionNumber[] = "1.0";
CHAR VersionTimestamp[] = __DATE__ " " __TIME__;
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_NOTIFY, ( VersionHerald, VersionNumber, VersionTimestamp) );
#endif
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("DriverEntry - IN\n") );
//
// Create extension for the driverobject to store driver specific
// information. Device specific information should be stored in
// Device Extension
status = IoAllocateDriverObjectExtension(DriverObject,
RAMDISK_DRIVER_EXTENSION_KEY,
sizeof(RAMDISK_DRIVER_EXTENSION),
&driverExtension);
if(!NT_SUCCESS(status)) {
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR,
("Ramdisk driver extension could not be allocated %lx \n", status ) );
return status;
}
//
// Copy the registry path into the driver extension so we can use it later
//
driverExtension->RegistryPath.Length = RegistryPath->Length;
driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength +
sizeof(UNICODE_NULL);
driverExtension->RegistryPath.Buffer =
ExAllocatePoolWithTag(PagedPool,
driverExtension->RegistryPath.MaximumLength,
RAMDISK_TAG_GENERAL);
if(driverExtension->RegistryPath.Buffer == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
RtlCopyUnicodeString( &(driverExtension->RegistryPath), RegistryPath);
driverExtension->DeviceInitialized = FALSE;
#if DBG
// Query registry paramters
RamDiskQueryDebugRegParameters( RegistryPath );
// Break if required
if ( BreakOnEntry ) {
KdBreakPoint();
}
#endif
//
// Create dispatch points for Create, Close, Unload, Pnp, Power & WMI
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = RamDiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamDiskCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = RamDiskReadWrite;
DriverObject->MajorFunction[IRP_MJ_WRITE] = RamDiskReadWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamDiskIOCtl;
DriverObject->MajorFunction[IRP_MJ_PNP] = RamDiskDispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = RamDiskDispatchPower;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = RamDiskDispatchSystemControl;
DriverObject->DriverExtension->AddDevice = RamDiskAddDevice;
DriverObject->DriverUnload = RamDiskUnload;
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("DriverEntry - OUT.\n") );
return STATUS_SUCCESS;
} // End of DriverEntry()
NTSTATUS
RamDiskCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system to create or close a
handle to the device that we control.
Arguments:
DeviceObject - a pointer to the object that represents the device
Irp - a pointer to the I/O Request Packet for this request.
Return Value:
STATUS_SUCCESS
--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("CreateClose - IN\n") );
irpStack = IoGetCurrentIrpStackLocation( Irp );
switch ( irpStack->MajorFunction ) {
case IRP_MJ_CREATE:
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("IRP_MJ_CREATE (%p)\n", Irp) );
COMPLETE_REQUEST( Irp, status, 0 );
break;
case IRP_MJ_CLOSE:
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("IRP_MJ_CLOSE (%p)\n", Irp) );
COMPLETE_REQUEST( Irp, status, 0 );
break;
default:
status = STATUS_NOT_IMPLEMENTED;
COMPLETE_REQUEST( Irp, status, 0 );
ASSERTMSG("BUG: we should never get here", 0);
break;
} // switch
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, ("CreateClose - OUT\n") );
return status;
} // End of RamDiskCreateClose()
VOID
RamDiskUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine is called when the driver is unloaded from the
system. This released the memory allocated during DriverEntry
Arguments:
DriverObject - a pointer to the driver object
Return Value:
None
--*/
{
PRAMDISK_DRIVER_EXTENSION driverExtension;
DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, ("Driver Unload\n") );
ASSERT(DriverObject->DeviceObject == NULL);
driverExtension = IoGetDriverObjectExtension(DriverObject,
RAMDISK_DRIVER_EXTENSION_KEY);
ASSERT ( driverExtension != NULL );
if ( driverExtension->RegistryPath.Buffer ) {
ExFreePool( driverExtension->RegistryPath.Buffer );
}
return;
} // End of RamDiskUnload()
NTSTATUS
RamDiskIOCtl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the IOCTL handler for our driver. This is called whenever
the driver on top sends any IOCTL requests
Arguments:
DeviceObject - a pointer to the object that represents the device
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 = STATUS_INVALID_DEVICE_REQUEST;
ULONG command;
ULONG information = 0;
PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_VERBOSE, ("IOCtl- IN \n" ) );
status = IoAcquireRemoveLock(&devExt->RemoveLock, Irp);
if (!NT_SUCCESS(status)) {
DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_ERROR, ("Acquire RemoveLock failed\n" ) );
COMPLETE_REQUEST( Irp, status, 0 );
return status;
}
irpStack = IoGetCurrentIrpStackLocation(Irp);
command = irpStack->Parameters.DeviceIoControl.IoControlCode;
switch ( command )
{
case IOCTL_DISK_GET_PARTITION_INFO: {
DBGPRINT( DBG_COMP_IOCTL, DBG_LEVEL_INFO, ("IOCTL_DISK_GET_PARTITION_INFO \n" ) );
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(PARTITION_INFORMATION)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -