From: Mike Pittelkow [mikep@xiotech.com] Sent: Tuesday, November 02, 1999 9:09 AM To: jkirby@storagecraft.com; robg@cdp.com Cc: ntdev@atria.com Subject: RE: [ntdev] New a version of IoReadPartitonTable() I've been around in circles with MS on this one too. Took a while to figure out. Here's my code for that function. It should be fairly easy to understand, but let me know if you need help. You have to cache the part. info in your device extension, and return it only if the device is not reserved. get_drive_layout is the only routine allowed to call getpartitioninformation (without recursing, anyway) There's a lot of contortions here to be sure my target device is not reserved. This is a lot like the sample code in the ddk (but more verbose) case IOCTL_DISK_GET_PARTITION_INFO: { PPARTITION_INFORMATION PartitionInfo = (PPARTITION_INFORMATION)OutputBuffer; NTSTATUS Status; PVRP_ENTRY mVRP; char * Sector; PMDL Mdl; UCHAR VRPStatus; if (PartitionExtension == DiskExtension->Partition0) { DbgPrint("XIO: Get partition information for partition0 is invalid.\n"); IRPSTATUS(Irp,STATUS_INVALID_DEVICE_REQUEST,0); break; } if (DiskExtension == NULL) { IRPSTATUS(Irp,STATUS_INVALID_DEVICE_REQUEST,0); break; } mVRP=GetUnbalancedVRP(DeviceExtension); // Get a VRP for a single sector if (mVRP != NULL) { Sector = ExAllocatePool(NonPagedPool,DiskExtension->BlockSize); if (Sector != NULL) { Mdl = IoAllocateMdl(Sector,DiskExtension->BlockSize,FALSE,FALSE,NULL); MmBuildMdlForNonPagedPool(Mdl); InitializeVRP(mVRP,VR_FUNC_READ,NULL,Mdl,1,FALSE,DiskExtension->VirtualID,0) ; mVRP->VRP->VRP_Entry.StartingAddress=0; if (!WaitForIO(mVRP,&VRPStatus,TRUE)) { IRPSTATUS(Irp,STATUS_DEVICE_BUSY,0); // The IO timed out, so fail this request } ExFreePool(Sector); if (VRPStatus != VR_STAT_OK) { IRPSTATUS(Irp,STATUS_DEVICE_BUSY,0); // Read was not successful, so fail the request break; } // If we got here, the read was usccessful, so go on to return that partition information } else { IRPSTATUS(Irp,STATUS_INSUFFICIENT_RESOURCES,0); // not enough resources to do a "check" io, so give up break; } } else { IRPSTATUS(Irp,STATUS_INVALID_DEVICE_REQUEST,0); // Fail if we can't get the VRP. break; } if (OutputBufferLength < sizeof(PARTITION_INFORMATION)) // Buffer is too small. { DbgPrint("XIO: Get partition information, buffer is too small.\n"); IRPSTATUS(Irp,STATUS_BUFFER_TOO_SMALL,0); break; } else //Buffer big enough, so copy the data. { RtlCopyMemory(PartitionInfo,&PartitionExtension->PartitionInformation,sizeof (PARTITION_INFORMATION)); PartitionInfo->RecognizedPartition = TRUE; PartitionInfo->RewritePartition = FALSE; DUMP_PARTITION(PartitionInfo,0xFF); IRPSTATUS(Irp,STATUS_SUCCESS,sizeof(PARTITION_INFORMATION)); break; } } case IOCTL_DISK_SET_DRIVE_LAYOUT: { PDRIVE_LAYOUT_INFORMATION DriveLayout = (PDRIVE_LAYOUT_INFORMATION)OutputBuffer; // Note: this is a little odd NTSTATUS Status; UCHAR Count; PPARTITION_INFORMATION PartInfo; if (DiskExtension == NULL) { IRPSTATUS(Irp,STATUS_INVALID_DEVICE_REQUEST,0); break; } if (InputBufferLength < sizeof(DRIVE_LAYOUT_INFORMATION)) { IRPSTATUS(Irp,STATUS_INFO_LENGTH_MISMATCH,0); break; } if (InputBufferLength < (sizeof(DRIVE_LAYOUT_INFORMATION)+(DriveLayout->PartitionCount - 1)*sizeof(PARTITION_INFORMATION))) { IRPSTATUS(Irp,STATUS_BUFFER_TOO_SMALL,0); break; } ResolvePartitionObjects(DriveLayout,DiskExtension); Status = IoWritePartitionTable(DiskExtension->Partition0->ThisPartition, DiskExtension->DiskGeometry.BytesPerSector, DiskExtension->DiskGeometry.SectorsPerTrack, DiskExtension->DiskGeometry.TracksPerCylinder, DriveLayout); if (!NT_SUCCESS(Status)) { IRPSTATUS(Irp,Status,0); break; } DUMP_PARTITION_TABLE(DriveLayout); IRPSTATUS(Irp,STATUS_SUCCESS,OutputBufferLength); break; } case IOCTL_DISK_GET_DRIVE_LAYOUT: { PDRIVE_LAYOUT_INFORMATION DriveLayout; PDRIVE_LAYOUT_INFORMATION OutputLayout = (PDRIVE_LAYOUT_INFORMATION)OutputBuffer; ULONG TotalSize = 0; NTSTATUS Status; if (DiskExtension == NULL) { IRPSTATUS(Irp,STATUS_INVALID_DEVICE_REQUEST,0); break; } DbgPrint("XIO: calling IoReadPartitionTable (DGDL)\n"); Status = IoReadPartitionTable(DiskExtension->Partition0->ThisPartition,DiskExtension- >BlockSize,FALSE,&DriveLayout); if (!NT_SUCCESS(Status)) { // DbgPrint("XIO: Get Drive Layout - Unable to read partition table.\n"); IRPSTATUS(Irp,Status,0); break; } TotalSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]); TotalSize = TotalSize + DriveLayout->PartitionCount * sizeof(PARTITION_INFORMATION); if (OutputBufferLength < TotalSize) // Buffer is too small. { ExFreePool(DriveLayout); DbgPrint("XIO: Get Drive Layout - buffer is too small.\n"); IRPSTATUS(Irp,STATUS_BUFFER_TOO_SMALL,0); break; } else //Buffer big enough, so copy the data. { ResolvePartitionObjects(DriveLayout,DiskExtension); DUMP_PARTITION_TABLE(DriveLayout); RtlCopyMemory(OutputLayout,DriveLayout,TotalSize); ExFreePool(DriveLayout); IRPSTATUS(Irp,STATUS_SUCCESS,TotalSize); break; } } > -----Original Message----- > From: owner-ntdev@atria.com [mailto:owner-ntdev@atria.com]On Behalf Of > jkirby@storagecraft.com > Sent: Monday, November 01, 1999 6:34 AM > To: robg@cdp.com > Cc: ntdev@atria.com > Subject: Re: [ntdev] New a version of IoReadPartitonTable() > > > No, it does not emulate the NT 4.0 functionality. Thanks for the thought. > > Jamey > > > On Sun, 31 October 1999, Rob Green wrote: > > > > > if you look at E:\NTDDK\src\storage\class\disk\drivesup.c that > have source > > code to xHalIoReadPartitionTable which is suppose to emulate > that function. > > > > What i do is just send the request on through and get the data > i need from > > the completion routine. > > > > rob > > > > > > At 10:47 AM 10/31/1999 , jkirby@storagecraft.com wrote: > > >All, > > > > > >I am porting a filter driver from NT 4.0 to Windows 2000. > Under NT 4.0, > > >IoReadPartitionTable() issues an IRP_MJ_READ to get the > partition table > > >from the disk. Under Windows 2000, IoReadPartitionTable() calls > > >IOCTL_DISK_GET_DRIVE_LAYOUT. Unfortunatly, in my > IOCTL_GET_DRIVE_LAYOUT > > >handler, I call IoReadPatrtitonTable() as well (I am a disk > filter). As > > >you can see, I hit recursion into my IOCTL_GET_DRIVE_LAYOUT handler. I > > >need some source code to demonstrate how to read the partiton > table and > > >build a DRIVE_LAYOPUT_INFORMATION structure like the 4.0 version of > > >IoReadPartitonTable(). > > > > > >I can write my own, it is only a matter of a couple of days to > write it > > >and test it. It would be much easier if someone already has code to do > > >this. I am under a extream deadline and don't really have the > extra couple > > >of days to write and debug the code. > > > > > >Amy help would be appreciated. > > > > > >Regards, > > > > > >Jamey Kirby > > >StorageCraft > > >www.storagecraft.com > > >jkirby@storagecraft.com > > > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > > >[ To unsubscribe, send email to ntdev-request@atria.com with body > > >UNSUBSCRIBE (the subject is ignored). ] > > > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > [ To unsubscribe, send email to ntdev-request@atria.com with body > UNSUBSCRIBE (the subject is ignored). ] > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ To unsubscribe, send email to ntdev-request@atria.com with body UNSUBSCRIBE (the subject is ignored). ]