> >- On a 32-bit system this is a pain to implement as you can imagine
since you need to play with PAE, create a selector system
>(guess what, your
> pointers are still 32-bit large), etc.
A selector system ? The kernel API’s do provide all what you need .
Take a look at “MmAllocatePagesForMdl”
[Edouard A.]
I’ve worked quite a bit on VMs but not that much on the NT VM. From what I understand of MmAllocatePagesForMDL, it still sounds like you have more work to do.
The problem I see is that you’re most likely not going to be able to have your chunks of physical memory to be contiguous, before calling MmAllocatePagesForMdl you will need to the…
Big offset -> selector / not so big offset -> omg which chunk was it already YA RLY
…translation.
I think it’ll be more clear if I write some incomplete code to show you what I had in mind:
uint64_t lBigAddress = lValue;
// we check that lBigAddress is below 36-bit…
if ((lBigAddress & 0xFFFFFFFFF) != lBigAddress)
// error… (on 32-bit PAE)
// Then we look up in our table…
vector::iterator itMdl = vecMdl[(lBigAddress >> 20) & 0xffff];
if (itMdl == NULL)
// not found => create? abort? die? call Chuck Norris?
// then we read/write into MDL + lBigAddress & 20-bit
As you can see in my example I use the high 16 bit as key which leads to physical chunks of 1 MB. That looks pretty much like a selector to me.
Did you have an idea to do it otherwise?
>
> > In theory a 8 GB ramdisk on a 64-bit operating system is no problem
> (and will probably be done in the future),
>
> They exist already in many flavours .
>
> Christiaan
>
>
> ----- Original Message -----
> From: “Edouard A.”
> To: “Windows System Software Devs Interest List”
> Sent: Wednesday, August 01, 2007 8:07 PM
> Subject: RE: [ntdev] How to increase the size of ram disk to 8 GB
>
>
>
> PAE doesn’t increase the virtual space size. PAE increases the size of
> physical memory available to the processor to a theoretical
> limit of 64 GB. You still have to do some work to access that memory.
>
> Not only that but with PAE enabled the page table and page directory
> double in size, this has consequences.
>
> When you have a server with 10 GB of RAM, you really want to install a
> 64-bit operating system.
>
>
> But that wasn’t the detail on which I was focused. My point was the
> following:
>
> - A ramdisk is made to have high-speed temporary storage
> - To make sense, you need much more than 8 GB of RAM otherwise you
> will be killing the whole system performance (smaller cache,
> less memory for other applications, useless swapping…) for the sake
> of this ramdisk. AFAIK system with much more than 8 GB or RAM
> are not frequent, even amongst servers.
> - On a 32-bit system this is a pain to implement as you can imagine
> since you need to play with PAE, create a selector system
> (guess what, your pointers are still 32-bit large), etc.
> - Even on a 64-bit system you have to implement some sort of two
> levels allocation, one small area of non-paged pool that buffers
> writes to a paged pool of 8 GB. That can nonetheless be done. In theory
> a 8 GB ramdisk on a 64-bit operating system is no problem
> (and will probably be done in the future), but right now it’s a bit
> useless…
>
> –
>
> EA
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com [mailto:bounce-295841-
> > xxxxx@lists.osr.com] On Behalf Of Christiaan Ghijselinck
> > Sent: mardi 31 juillet 2007 16:56
> > To: Windows System Software Devs Interest List
> > Subject: Re: [ntdev] How to increase the size of ram disk to 8 GB
> >
> >
> >
> > >>I would like to know the point of having a 8 GB ramdisk… Sounds
> to
> > me
> > >>bigger than the amount of physical memory you might have… And on
> a
> > 32-bit
> > >>system you will have to build some sort of selector system… A VM
> > inside
> > >>the VM yeah but… …no thanks.
> > >>In other words: “f00lz! ur me551nG w1tH d4Rk m4g1k!!!”.
> >
> > Concotion ! If you have 10 GB of physical RAM , you can easely grab
> > free 8 GB of it with 32 bit Server 2003. Never heard of PAE ?
> >
> >
> > Christiaan
> >
> >
> > –
> >
> > Edouard A.
> >
> > Le Mon, 30 Jul 2007 19:35:52 -0400, “Martin O’Brien”
> > a ecrit:
> > > 1. This code is unreadable, at least as it got rendered in the e-
> > mail.
> > > No one wants to struggle with stuff like this for no reason.
> > >
> > > 2. As Tim possibly among others has pointed out a few times, the
> > code
> > > to map pages in and out is quite a bit of work and really not all
> > that
> > > simple.
> > >
> > > 3. Do you really need such a large RAM disk that badly? Given you
> > > apparent experience level, you have months of work for something
> that
> > is
> > > hard to imagine as vital.
> > >
> > > mm
> > >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com] On Behalf Of
> > > xxxxx@yahoo.com
> > > Sent: Monday, July 30, 2007 18:18
> > > To: Windows System Software Devs Interest List
> > > Subject: RE:[ntdev] How to increase the size of ram disk to 8 GB
> > >
> > > Hello Don Burn
> > > I think you are much familier with this code.
> > > Yeah, in PNP.c there is a ExAllocatePool moudle. Can you give some
> > > little
> > > code, how to map the pages. Here below is the whole code for the
> > PnP.c
> > >
> > > /++
> > > Copyright (c) 1990-2000 Microsoft Corporation, All Rights
> Reserved
> > > Module Name:
> > > pnp.c
> > > Abstract:
> > > This is the code for handling PnP, Power and WMI IRPs
> > > Author:
> > > Raju Ramanathan 02/22/2000
> > > Enviroment:
> > > Kernel Mode Only
> > > Revision History:
> > > Code cleaning 04/19/2000
> > > –/
> > > #include <stdio.h>
> > > #include “ntddk.h”
> > > #include “debug.h”
> > > #include “ramdisk.h”
> > > PCSTR StateTable[] ={
> > > { “STOPPED” },
> > > { “WORKING” },
> > > { “PENDINGSTOP” },
> > > { “PENDINGREMOVE” },
> > > { “SURPRISEREMOVED” },
> > > { “REMOVED” },
> > > { “UNKNOWN” }
> > > };
> > > NTSTATUS
> > > RamDiskAddDevice(
> > > IN PDRIVER_OBJECT DriverObject,
> > > IN PDEVICE_OBJECT PhysicalDeviceObject
> > > )
> > > /++
> > > Routine Description:
> > > AddDevice routine to create the device object and symbolic link
> > >
> > > Arguments:
> > > DriverObject - Supplies the driver object
> > > PhysicalDeviceObject - Supplies the physical device object
> > >
> > > Return Value:
> > > NTSTATUS
> > >
> > > –/
> > > {
> > > PRAMDISK_DRIVER_EXTENSION driverExtension;
> > > PDEVICE_OBJECT functionDeviceObject;
> > > PDEVICE_EXTENSION devExt;
> > > UNICODE_STRING uniDeviceName;
> > > UNICODE_STRING uniWin32Name;
> > > NTSTATUS status = STATUS_SUCCESS;
> > >
> > > PAGED_CODE();
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, (“AddDevice - IN.
> > > DriverObject=(%p) Pdo=(%p) \n”,
> > > DriverObject, PhysicalDeviceObject ) );
> > > // Get the Driver object extension
> > > driverExtension = IoGetDriverObjectExtension(DriverObject,
> > > RAMDISK_DRIVER_EXTENSION_KEY);
> > > ASSERT ( driverExtension != NULL );
> > > //
> > > // We are capable of handling only one device. If the we get
> > > AddDevice request
> > > // for the next device, reject it
> > > //
> > > if ( driverExtension->DeviceInitialized == TRUE ) {
> > > DBGPRINT (DBG_COMP_INIT, DBG_LEVEL_ERROR, (“Device exists\n”) );
> > > return (STATUS_DEVICE_ALREADY_ATTACHED);
> > > }
> > > //
> > > // Create counted string version of our device name.
> > > //
> > > RtlInitUnicodeString( &uniDeviceName, NT_DEVICE_NAME );
> > > //
> > > // Create the device object
> > > //
> > > status = IoCreateDevice(
> > > DriverObject,
> > > sizeof(DEVICE_EXTENSION),
> > > &uniDeviceName,
> > > FILE_DEVICE_VIRTUAL_DISK,
> > > (FILE_DEVICE_SECURE_OPEN),
> > > FALSE, // This isn’t an exclusive device
> > > &functionDeviceObject
> > > );
> > > if (!NT_SUCCESS(status))
> > > {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, (“IoCreateDevice error:
> > > 0x%x\n”, status) );
> > > return status;
> > > }
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_INFO, (“FDO created
> successfully
> > > (%p)\n”,
> > > functionDeviceObject) );
> > > devExt = functionDeviceObject->DeviceExtension;
> > > RtlZeroMemory( devExt, sizeof(DEVICE_EXTENSION) );
> > > // Allocate buffer for storing the drive letter
> > > devExt->DiskRegInfo.DriveLetter.Buffer = ExAllocatePoolWithTag(
> > > PagedPool,
> > > DRIVE_LETTER_LENGTH,
> > > RAMDISK_TAG_GENERAL);
> > > if ( devExt->DiskRegInfo.DriveLetter.Buffer == NULL ) {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, (“Can’t allocate memory
> > for
> > > drive letter\n”) );
> > > RamDiskCleanUp( functionDeviceObject );
> > > return STATUS_INSUFFICIENT_RESOURCES;
> > > }
> > > devExt->DiskRegInfo.DriveLetter.MaximumLength =
> > DRIVE_LETTER_LENGTH;
> > > //
> > > // Get the disk parameters from the registry
> > > //
> > > RamDiskQueryDiskRegParameters( &driverExtension->RegistryPath,
> > > &devExt->DiskRegInfo );
> > > devExt->PhysicalDeviceObject = PhysicalDeviceObject; // Save PDO
> > > pointer
> > > devExt->DeviceObject = functionDeviceObject; // Save device
> object
> > > pointer
> > > devExt->DevState = STOPPED; // Device starts in Stopped state
> > > IoInitializeRemoveLock ( &devExt->RemoveLock,
> > > REMLOCK_TAG,
> > > REMLOCK_MAXIMUM,
> > > REMLOCK_HIGHWATER);
> > > // Set device flags
> > > functionDeviceObject->Flags |= DO_POWER_PAGABLE;
> > > functionDeviceObject->Flags |= DO_DIRECT_IO;
> > > //
> > > // Allocate the memory for disk image.
> > > //
> > >
> > > devExt->DiskImage = ExAllocatePoolWithTag(
> > > NonPagedPool,
> > > devExt->DiskRegInfo.DiskSize,
> > > RAMDISK_TAG_DISK);
> > >
> > > if ( devExt->DiskImage == NULL )
> > > {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, (“Can’t allocate memory
> > for
> > > disk image\n”) );
> > > RamDiskCleanUp( functionDeviceObject );
> > > return STATUS_INSUFFICIENT_RESOURCES;
> > > }
> > > // Format the disk
> > > RamDiskFormatDisk( functionDeviceObject );
> > > // Create symbolic link, which is the drive letter for the
> ramdisk
> > > devExt->SymbolicLink.Buffer = ExAllocatePoolWithTag(
> > > PagedPool,
> > > DOS_DEVNAME_LENGTH,
> > > RAMDISK_TAG_GENERAL);
> > > if ( devExt->SymbolicLink.Buffer == NULL ) {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, (“Can’t allocate memory
> > for
> > > symbolic link\n”) );
> > > RamDiskCleanUp( functionDeviceObject );
> > > return STATUS_INSUFFICIENT_RESOURCES;
> > > }
> > > RtlInitUnicodeString( &uniWin32Name, DOS_DEVICE_NAME );
> > > devExt->SymbolicLink.MaximumLength = DOS_DEVNAME_LENGTH;
> > > devExt->SymbolicLink.Length = uniWin32Name.Length;
> > > RtlCopyUnicodeString( &(devExt->SymbolicLink), &uniWin32Name );
> > > RtlAppendUnicodeStringToString( &(devExt->SymbolicLink),
> > > &(devExt->DiskRegInfo.DriveLetter) );
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_NOTIFY, (“Creating drive
> letter
> > =
> > > %wZ\n”,&(devExt->SymbolicLink) ) );
> > > // Create a drive letter from our device name to a name in the
> > Win32
> > > namespace.
> > >
> > > status = IoCreateSymbolicLink( &devExt->SymbolicLink,
> > &uniDeviceName
> > > );
> > > if (!NT_SUCCESS(status)) {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR, (“IoCreateSymbolicLink
> > > error: 0x%x\n”, status) );
> > > RamDiskCleanUp( functionDeviceObject );
> > > return status;
> > > }
> > > devExt->Flags |= FLAG_LINK_CREATED;
> > > devExt->LowerDeviceObject =
> > > IoAttachDeviceToDeviceStack( functionDeviceObject,
> > > PhysicalDeviceObject );
> > > if ( devExt->LowerDeviceObject == NULL ) {
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_ERROR,
> > > (“IoAttachDeviceToDeviceStack error\n”) );
> > > RamDiskCleanUp( functionDeviceObject );
> > > return STATUS_NO_SUCH_DEVICE;
> > > }
> > > driverExtension->DeviceInitialized = TRUE;
> > > // Clear DO_DEVICE_INITIALIZING flag
> > > functionDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
> > > DBGPRINT( DBG_COMP_INIT, DBG_LEVEL_VERBOSE, (“AddDevice - OUT.
> > > Fdo=(%p) LowerDevice=(%p)\n”,
> > > functionDeviceObject, devExt->LowerDeviceObject ) );
> > > return status;
> > > } // End of RamDiskAddDevice()
> > > NTSTATUS
> > > RamDiskDispatchPnp(
> > > IN PDEVICE_OBJECT DeviceObject,
> > > IN PIRP Irp
> > > )
> > > /++
> > > Routine Description:
> > > Dispatch routine for Plug and Play IRPs
> > >
> > > Arguments:
> > > DeviceObject - Supplies the device object.
> > >
> > > Irp - Supplies the I/O request packet.
> > > Return Value:
> > > NTSTATUS
> > >
> > > –/
> > > {
> > > PIO_STACK_LOCATION irpStack;
> > > PDEVICE_EXTENSION devExt;
> > > KEVENT event;
> > > NTSTATUS status = STATUS_SUCCESS;
> > > BOOLEAN lockHeld = TRUE;
> > >
> > > PAGED_CODE();
> > > irpStack = IoGetCurrentIrpStackLocation( Irp );
> > > devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
> > > ASSERT( devExt->DevState < MAX_STATE );
> > > DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_INFO, (“DispatchPnP - IN.
> > Fdo=(%p)
> > > Irp=(%p) %s Device State=%s\n”,
> > > DeviceObject, Irp, GetPnpIrpName(irpStack->MinorFunction),
> > > StateTable[devExt->DevState] ) );
> > > 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;
> > > }
> > > switch (irpStack->MinorFunction) {
> > >
> > > case IRP_MN_START_DEVICE: {
> > > KeInitializeEvent( &event, NotificationEvent, FALSE);
> > > IoCopyCurrentIrpStackLocationToNext( Irp );
> > > IoSetCompletionRoutine( Irp, (PIO_COMPLETION_ROUTINE)
> > > RamDiskIoCompletionRoutine,
> > > (PVOID) &event, TRUE, TRUE, TRUE );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > if (status == STATUS_PENDING) {
> > > KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL
> > );
> > > }
> > > if ( NT_SUCCESS(status) ) {
> > > //
> > > // Device started successfully by the lower driver
> > > //
> > > devExt->DevState = WORKING;
> > > }
> > > COMPLETE_REQUEST( Irp, status, 0 );
> > > break;
> > > }
> > > case IRP_MN_QUERY_STOP_DEVICE: {
> > > devExt->DevState = PENDINGSTOP;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > break;
> > > }
> > > case IRP_MN_CANCEL_STOP_DEVICE: {
> > > //
> > > // Before sending the IRP down make sure we have received
> > > // a IRP_MN_QUERY_STOP_DEVICE. We may get Cancel Stop
> > > // without receiving a Query Stop earlier, if the
> > > // driver on top fails a Query Stop and passes down the
> > > // Cancel Stop.
> > > //
> > > if ( devExt->DevState == PENDINGSTOP ) {
> > > devExt->DevState = WORKING;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > } else {
> > > //
> > > // A spurious Cancel Stop request. Just complete it
> > > //
> > > status = STATUS_SUCCESS;
> > > COMPLETE_REQUEST( Irp, status, 0 );
> > > }
> > > break;
> > > }
> > > case IRP_MN_STOP_DEVICE: {
> > > devExt->DevState = STOPPED;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > break;
> > > }
> > >
> > > case IRP_MN_QUERY_REMOVE_DEVICE: {
> > > devExt->DevState = PENDINGREMOVE;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > break;
> > > }
> > > case IRP_MN_CANCEL_REMOVE_DEVICE: {
> > > //
> > > // Before sending the IRP down make sure we have received
> > > // a IRP_MN_QUERY_REMOVE_DEVICE. We may get Cancel Remove
> > > // without receiving a Query Remove earlier, if the
> > > // driver on top fails a Query Remove and passes down the
> > > // Cancel Remove.
> > > //
> > > if ( devExt->DevState == PENDINGREMOVE ) {
> > > devExt->DevState = WORKING;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > } else {
> > > //
> > > // A spurious Cancel Remove request. Just complete it
> > > //
> > > status = STATUS_SUCCESS;
> > > COMPLETE_REQUEST( Irp, status, 0 );
> > > }
> > > break;
> > > }
> > > case IRP_MN_SURPRISE_REMOVAL: {
> > > devExt->DevState = SURPRISEREMOVED;
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > break;
> > > }
> > > case IRP_MN_REMOVE_DEVICE: {
> > > RamDiskRemoveDevice( DeviceObject, Irp );
> > > //
> > > // Remove Lock released by RamDiskRemoveDevice
> > > //
> > > lockHeld = FALSE;
> > > break;
> > > }
> > > default: {
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > break;
> > > } // default
> > > } // switch
> > > //
> > > // Device Extenion is gone if the current IRP is
> > IRP_MN_REMOVE_DEVICE
> > > //
> > > if ( lockHeld == TRUE ) {
> > > IoReleaseRemoveLock(&devExt->RemoveLock, Irp);
> > > DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_INFO, (“DispatchPnP - OUT.
> Device
> > > State=%s\n”,
> > > StateTable[devExt->DevState] ) );
> > > }
> > > return status;
> > > } // End of RamDiskDispatchPnp()
> > > NTSTATUS
> > > RamDiskDispatchPower(
> > > IN PDEVICE_OBJECT DeviceObject,
> > > IN PIRP Irp
> > > )
> > > /++
> > > Routine Description:
> > > Dispatch routine for Power management IRPs
> > >
> > > Arguments:
> > > DeviceObject - Supplies the device object.
> > >
> > > Irp - Supplies the I/O request packet.
> > > Return Value:
> > > NTSTATUS
> > >
> > > –/
> > > {
> > > PDEVICE_EXTENSION devExt;
> > > NTSTATUS status = STATUS_SUCCESS;
> > > PAGED_CODE();
> > > DBGPRINT( DBG_COMP_POWER, DBG_LEVEL_VERBOSE, (“DispatchPower -
> IN.
> > > Fdo=(%p) Irp=(%p)\n”,
> > > DeviceObject, Irp ) );
> > > devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
> > > //
> > > // If the device has been removed, the driver should not pass
> > > // the IRP down to the next lower driver.
> > > //
> > > if ( devExt->DevState == REMOVED) {
> > > PoStartNextPowerIrp( Irp );
> > > status = STATUS_DELETE_PENDING;
> > > COMPLETE_REQUEST( Irp, status, 0 );
> > > return status;
> > > }
> > > PoStartNextPowerIrp( Irp );
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > DBGPRINT( DBG_COMP_POWER, DBG_LEVEL_VERBOSE, (“DispatchPower -
> > > OUT.\n” ) );
> > > return PoCallDriver( devExt->LowerDeviceObject, Irp );
> > > } // End of RamDiskDispatchPower()
> > > NTSTATUS
> > > RamDiskDispatchSystemControl(
> > > IN PDEVICE_OBJECT DeviceObject,
> > > IN PIRP Irp
> > > )
> > > /++
> > > Routine Description:
> > > Dispatch routine for WMI IRPs. It just forwards the
> > > IRPs to the lower driver.
> > >
> > > Arguments:
> > > DeviceObject - Supplies the device object.
> > >
> > > Irp - Supplies the I/O request packet.
> > > Return Value:
> > > NTSTATUS
> > >
> > > –/
> > > {
> > > PDEVICE_EXTENSION devExt;
> > > PAGED_CODE();
> > > DBGPRINT( DBG_COMP_WMI, DBG_LEVEL_VERBOSE,
> (“DispatchSystemControl
> > -
> > > IN. Fdo=(%p) Irp=(%p)\n”,
> > > DeviceObject, Irp ) );
> > > devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > DBGPRINT( DBG_COMP_WMI, DBG_LEVEL_VERBOSE,
> (“DispatchSystemControl
> > -
> > > OUT.\n” ) );
> > > return IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > } // End of RamDiskDispatchSystemControl()
> > >
> > > NTSTATUS
> > > RamDiskIoCompletionRoutine(
> > > IN PDEVICE_OBJECT DeviceObject,
> > > IN PIRP Irp,
> > > IN PKEVENT Event
> > > )
> > > /++
> > > Routine Description:
> > > Io completion routine
> > >
> > > Arguments:
> > > DeviceObject - Supplies the device object.
> > >
> > > Irp - Supplies the I/O request packet.
> > > Event - Supplies the Event to be set.
> > > Return Value:
> > > NTSTATUS
> > >
> > > –/
> > > {
> > > KeSetEvent( Event, 0, FALSE );
> > > return STATUS_MORE_PROCESSING_REQUIRED;
> > > } // End of RamDiskIoCompletionRoutine()
> > >
> > > VOID
> > > RamDiskCleanUp(
> > > IN PDEVICE_OBJECT DeviceObject
> > > )
> > > /++
> > > Routine Description:
> > > This routine does the required cleaning like deleting the
> symbolic
> > > link
> > > releasjing the memory etc.
> > > Arguments:
> > > DeviceObject - Supplies a pointer to the device object that
> > > represents
> > > the device whose capacity is to be read.
> > > Return Value:
> > > None.
> > > –/
> > > {
> > >
> > > PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
> > > PAGED_CODE();
> > > DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_VERBOSE, (“RamDiskCleanUp\n” )
> );
> > >
> > > if ( devExt->Flags & FLAG_LINK_CREATED ) {
> > > IoDeleteSymbolicLink( &devExt->SymbolicLink );
> > > }
> > > if ( devExt->SymbolicLink.Buffer ) {
> > > ExFreePool( devExt->SymbolicLink.Buffer );
> > > }
> > > if ( devExt->DiskRegInfo.DriveLetter.Buffer ) {
> > > ExFreePool( devExt->DiskRegInfo.DriveLetter.Buffer );
> > > }
> > > if ( devExt->DiskImage ) {
> > > ExFreePool( devExt->DiskImage );
> > > }
> > > if ( devExt->LowerDeviceObject ) {
> > > IoDetachDevice( devExt->LowerDeviceObject );
> > > }
> > > IoDeleteDevice( DeviceObject );
> > > return;
> > > }
> > > VOID
> > > RamDiskRemoveDevice(
> > > IN PDEVICE_OBJECT DeviceObject,
> > > IN PIRP Irp
> > > )
> > > /++
> > > Routine Description:
> > > This routine releases the remove lock and calls RamDiskCleanUp
> > > to do the cleaning
> > > Arguments:
> > > DeviceObject - Supplies a pointer to the device object that
> > > represents
> > > the device whose capacity is to be read.
> > > Return Value:
> > > None.
> > > –/
> > > {
> > > PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
> > > PRAMDISK_DRIVER_EXTENSION driverExtension;
> > > NTSTATUS status;
> > > PAGED_CODE();
> > > DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_VERBOSE, (“RemoveDevice\n” ) );
> > > Irp->IoStatus.Status = STATUS_SUCCESS;
> > > IoSkipCurrentIrpStackLocation( Irp );
> > > status = IoCallDriver( devExt->LowerDeviceObject, Irp );
> > > //
> > > // Set the device status to REMOVED and wait for other drivers
> > > // to release the lock, then delete the device object
> > > //
> > > devExt->DevState = REMOVED;
> > > IoReleaseRemoveLockAndWait(&devExt->RemoveLock, Irp);
> > > driverExtension =
> > > IoGetDriverObjectExtension(DeviceObject->DriverObject,
> > > RAMDISK_DRIVER_EXTENSION_KEY);
> > > ASSERT ( driverExtension != NULL );
> > > driverExtension->DeviceInitialized = FALSE;
> > > RamDiskCleanUp( DeviceObject );
> > > DBGPRINT( DBG_COMP_PNP, DBG_LEVEL_NOTIFY, (“Device Removed
> > > succesfully\n” ) );
> > > return;
> > > } // end RamDiskRemoveDevice()
> > >
> > > PSTR
> > > GetPnpIrpName(
> > > IN UCHAR PnpMinorFunction
> > > )
> > > /++
> > > Routine Description:
> > > This function returns the minor function string for
> > > the given id.
> > >
> > > Arguments:
> > > PnpMinorFunction - Supplies the Minor function Irp id.
> > >
> > > Return Value:
> > > PSTR - Function name string
> > >
> > > --*/
> > > {
> > > static char functionName[80];
> > > PAGED_CODE();
> > > switch ( PnpMinorFunction ) {
> > > case IRP_MN_START_DEVICE: // 0x00
> > > return “IRP_MN_START_DEVICE”;
> > > break;
> > > case IRP_MN_QUERY_REMOVE_DEVICE: // 0x01
> > > return “IRP_MN_QUERY_REMOVE_DEVICE”;
> > > break;
> > > case IRP_MN_REMOVE_DEVICE: // 0x02
> > > return “IRP_MN_REMOVE_DEVICE”;
> > > break;
> > > case IRP_MN_CANCEL_REMOVE_DEVICE: // 0x03
> > > return “IRP_MN_CANCEL_REMOVE_DEVICE”;
> > > break;
> > > case IRP_MN_STOP_DEVICE: // 0x04
> > > return “IRP_MN_STOP_DEVICE”;
> > > break;
> > > case IRP_MN_QUERY_STOP_DEVICE: // 0x05
> > > return “IRP_MN_QUERY_STOP_DEVICE”;
> > > break;
> > > case IRP_MN_CANCEL_STOP_DEVICE: // 0x06
> > > return “IRP_MN_CANCEL_STOP_DEVICE”;
> > > break;
> > > case IRP_MN_QUERY_DEVICE_RELATIONS: // 0x07
> > > return “IRP_MN_QUERY_DEVICE_RELATIONS”;
> > > break;
> > > case IRP_MN_QUERY_INTERFACE: // 0x08
> > > return “IRP_MN_QUERY_INTERFACE”;
> > > break;
> > > case IRP_MN_QUERY_CAPABILITIES: // 0x09
> > > return “IRP_MN_QUERY_CAPABILITIES”;
> > > break;
> > > case IRP_MN_QUERY_RESOURCES: // 0x0A
> > > return “IRP_MN_QUERY_RESOURCES”;
> > > break;
> > > case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: // 0x0B
> > > return “IRP_MN_QUERY_RESOURCE_REQUIREMENTS”;
> > > break;
> > > case IRP_MN_QUERY_DEVICE_TEXT: // 0x0C
> > > return “IRP_MN_QUERY_DEVICE_TEXT”;
> > > break;
> > > case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: // 0x0D
> > > return “IRP_MN_FILTER_RESOURCE_REQUIREMENTS”;
> > > break;
> > > case IRP_MN_READ_CONFIG: // 0x0F
> > > return “IRP_MN_READ_CONFIG”;
> > > break;
> > > case IRP_MN_WRITE_CONFIG: // 0x10
> > > return “IRP_MN_WRITE_CONFIG”;
> > > break;
> > > case IRP_MN_EJECT: // 0x11
> > > return “IRP_MN_EJECT”;
> > > break;
> > > case IRP_MN_SET_LOCK: // 0x12
> > > return “IRP_MN_SET_LOCK”;
> > > break;
> > > case IRP_MN_QUERY_ID: // 0x13
> > > return “IRP_MN_QUERY_ID”;
> > > break;
> > > case IRP_MN_QUERY_PNP_DEVICE_STATE: // 0x14
> > > return “IRP_MN_QUERY_PNP_DEVICE_STATE”;
> > > break;
> > > case IRP_MN_QUERY_BUS_INFORMATION: // 0x15
> > > return “IRP_MN_QUERY_BUS_INFORMATION”;
> > > break;
> > > case IRP_MN_DEVICE_USAGE_NOTIFICATION: // 0x16
> > > return “IRP_MN_DEVICE_USAGE_NOTIFICATION”;
> > > break;
> > > case IRP_MN_SURPRISE_REMOVAL: // 0x17
> > > return “IRP_MN_SURPRISE_REMOVAL”;
> > > break;
> > > case IRP_MN_QUERY_LEGACY_BUS_INFORMATION: // 0x18
> > > return “IRP_MN_QUERY_LEGACY_BUS_INFORMATION”;
> > > break;
> > > default:
> > > sprintf( functionName, “Unknown IRP(0x%x)”, PnpMinorFunction );
> > > return functionName;
> > > break;
> > > } // switch
> > > } // End of GetPnpIrpName()
> > >
> > >
> > >
> > > —
> > > NTDEV is sponsored by OSR
> > >
> > > For our schedule of WDF, WDM, debugging and other seminars visit:
> > > http://www.osr.com/seminars
> > >
> > > To unsubscribe, visit the List Server section of OSR Online at
> > > http://www.osronline.com/page.cfm?name=ListServer
> > >
> > > —
> > > NTDEV is sponsored by OSR
> > >
> > > For our schedule of WDF, WDM, debugging and other seminars visit:
> > > http://www.osr.com/seminars
> > >
> > > To unsubscribe, visit the List Server section of OSR Online at
> > > http://www.osronline.com/page.cfm?name=ListServer
> > –
> >
> > EA
> >
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
> >
> > —
> > NTDEV is sponsored by OSR
> >
> > For our schedule of WDF, WDM, debugging and other seminars visit:
> > http://www.osr.com/seminars
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer</stdio.h>