3 * Copyright (C) 2001, 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: disk.c,v 1.9 2002/03/13 01:30:34 ekohl Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/storage/disk/disk.c
24 * PURPOSE: disk class driver
25 * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
32 #include "../include/scsi.h"
33 #include "../include/class2.h"
34 #include "../include/ntddscsi.h"
39 #define VERSION "0.0.1"
42 typedef struct _DISK_DATA
45 ULONG PartitionNumber
;
47 BOOLEAN BootIndicator
;
48 BOOLEAN DriveNotReady
;
49 } DISK_DATA
, *PDISK_DATA
;
53 DiskClassFindDevices(PDRIVER_OBJECT DriverObject
,
54 PUNICODE_STRING RegistryPath
,
55 PCLASS_INIT_DATA InitializationData
,
56 PDEVICE_OBJECT PortDeviceObject
,
60 DiskClassCheckDevice(IN PINQUIRYDATA InquiryData
);
63 DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject
,
68 DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject
,
69 IN PUNICODE_STRING RegistryPath
, /* what's this used for? */
70 IN PDEVICE_OBJECT PortDeviceObject
,
73 IN PIO_SCSI_CAPABILITIES Capabilities
,
74 IN PSCSI_INQUIRY_DATA InquiryData
,
75 IN PCLASS_INIT_DATA InitializationData
);
78 DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
82 DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject
,
87 /* FUNCTIONS ****************************************************************/
92 // This function initializes the driver, locates and claims
93 // hardware resources, and creates various NT objects needed
94 // to process I/O requests.
100 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
102 // IN PUNICODE_STRING RegistryPath Name of registry driver service
109 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
110 IN PUNICODE_STRING RegistryPath
)
112 CLASS_INIT_DATA InitData
;
114 DbgPrint("Disk Class Driver %s\n",
116 DPRINT("RegistryPath '%wZ'\n",
119 RtlZeroMemory(&InitData
,
120 sizeof(CLASS_INIT_DATA
));
122 InitData
.InitializationDataSize
= sizeof(CLASS_INIT_DATA
);
123 InitData
.DeviceExtensionSize
= sizeof(DEVICE_EXTENSION
) + sizeof(DISK_DATA
);
124 InitData
.DeviceType
= FILE_DEVICE_DISK
;
125 InitData
.DeviceCharacteristics
= 0;
127 InitData
.ClassError
= NULL
; // DiskClassProcessError;
128 InitData
.ClassReadWriteVerification
= DiskClassCheckReadWrite
;
129 InitData
.ClassFindDeviceCallBack
= DiskClassCheckDevice
;
130 InitData
.ClassFindDevices
= DiskClassFindDevices
;
131 InitData
.ClassDeviceControl
= DiskClassDeviceControl
;
132 InitData
.ClassShutdownFlush
= DiskClassShutdownFlush
;
133 InitData
.ClassCreateClose
= NULL
;
134 InitData
.ClassStartIo
= NULL
;
136 return(ScsiClassInitialize(DriverObject
,
142 /**********************************************************************
144 * DiskClassFindDevices
147 * This function searches for device that are attached to the
155 * System allocated Driver Object for this driver
158 * Name of registry driver service key
161 * Pointer to the main initialization data
164 * Pointer to the port Device Object
170 * TRUE: At least one disk drive was found
171 * FALSE: No disk drive found
175 DiskClassFindDevices(PDRIVER_OBJECT DriverObject
,
176 PUNICODE_STRING RegistryPath
,
177 PCLASS_INIT_DATA InitializationData
,
178 PDEVICE_OBJECT PortDeviceObject
,
181 PCONFIGURATION_INFORMATION ConfigInfo
;
182 PIO_SCSI_CAPABILITIES PortCapabilities
;
183 PSCSI_ADAPTER_BUS_INFO AdapterBusInfo
;
184 PSCSI_INQUIRY_DATA UnitInfo
;
185 PINQUIRYDATA InquiryData
;
192 DPRINT("DiskClassFindDevices() called.\n");
194 /* Get port capabilities */
195 Status
= ScsiClassGetCapabilities(PortDeviceObject
,
197 if (!NT_SUCCESS(Status
))
199 DPRINT("ScsiClassGetCapabilities() failed! (Status 0x%lX)\n", Status
);
203 DPRINT("MaximumTransferLength: %lu\n", PortCapabilities
->MaximumTransferLength
);
205 /* Get inquiry data */
206 Status
= ScsiClassGetInquiryData(PortDeviceObject
,
207 (PSCSI_ADAPTER_BUS_INFO
*)&Buffer
);
208 if (!NT_SUCCESS(Status
))
210 DPRINT("ScsiClassGetInquiryData() failed! (Status %x)\n", Status
);
214 /* Check whether there are unclaimed devices */
215 AdapterBusInfo
= (PSCSI_ADAPTER_BUS_INFO
)Buffer
;
216 DeviceCount
= ScsiClassFindUnclaimedDevices(InitializationData
,
218 if (DeviceCount
== 0)
220 DPRINT1("No unclaimed devices!\n");
224 DPRINT("Found %lu unclaimed devices!\n", DeviceCount
);
226 ConfigInfo
= IoGetConfigurationInformation();
228 /* Search each bus of this adapter */
229 for (Bus
= 0; Bus
< (ULONG
)AdapterBusInfo
->NumberOfBuses
; Bus
++)
231 DPRINT("Searching bus %lu\n", Bus
);
233 UnitInfo
= (PSCSI_INQUIRY_DATA
)(Buffer
+ AdapterBusInfo
->BusData
[Bus
].InquiryDataOffset
);
235 while (AdapterBusInfo
->BusData
[Bus
].InquiryDataOffset
)
237 InquiryData
= (PINQUIRYDATA
)UnitInfo
->InquiryData
;
239 if (((InquiryData
->DeviceType
== DIRECT_ACCESS_DEVICE
) ||
240 (InquiryData
->DeviceType
== OPTICAL_DEVICE
)) &&
241 (InquiryData
->DeviceTypeQualifier
== 0) &&
242 (UnitInfo
->DeviceClaimed
== FALSE
))
244 DPRINT("Vendor: '%.24s'\n",
245 InquiryData
->VendorId
);
247 /* Create device objects for disk */
248 Status
= DiskClassCreateDeviceObject(DriverObject
,
252 ConfigInfo
->DiskCount
,
256 if (NT_SUCCESS(Status
))
258 ConfigInfo
->DiskCount
++;
263 if (UnitInfo
->NextInquiryDataOffset
== 0)
266 UnitInfo
= (PSCSI_INQUIRY_DATA
)(Buffer
+ UnitInfo
->NextInquiryDataOffset
);
271 ExFreePool(PortCapabilities
);
273 DPRINT("DiskClassFindDevices() done\n");
279 /**********************************************************************
281 * DiskClassCheckDevice
284 * This function checks the InquiryData for the correct device
285 * type and qualifier.
292 * Pointer to the inquiry data for the device in question.
295 * TRUE: A disk device was found.
300 DiskClassCheckDevice(IN PINQUIRYDATA InquiryData
)
302 return((InquiryData
->DeviceType
== DIRECT_ACCESS_DEVICE
||
303 InquiryData
->DeviceType
== OPTICAL_DEVICE
) &&
304 InquiryData
->DeviceTypeQualifier
== 0);
308 /**********************************************************************
310 * DiskClassCheckReadWrite
313 * This function checks the given IRP for correct data.
320 * Pointer to the device.
326 * STATUS_SUCCESS: The IRP matches the requirements of the given device.
331 DiskClassCheckReadWrite(IN PDEVICE_OBJECT DeviceObject
,
334 DPRINT1("DiskClassCheckReadWrite() called\n");
336 return(STATUS_SUCCESS
);
340 // DiskClassCreateDeviceObject
343 // Create the raw device and any partition devices on this drive
349 // IN PDRIVER_OBJECT DriverObject The system created driver object
350 // IN PCONTROLLER_OBJECT ControllerObject
351 // IN PIDE_CONTROLLER_EXTENSION ControllerExtension
352 // The IDE controller extension for
354 // IN int DriveIdx The index of the drive on this
356 // IN int HarddiskIdx The NT device number for this
360 // TRUE Drive exists and devices were created
361 // FALSE no devices were created for this device
365 DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject
,
366 IN PUNICODE_STRING RegistryPath
, /* what's this used for? */
367 IN PDEVICE_OBJECT PortDeviceObject
,
370 IN PIO_SCSI_CAPABILITIES Capabilities
,
371 IN PSCSI_INQUIRY_DATA InquiryData
,
372 IN PCLASS_INIT_DATA InitializationData
)
374 OBJECT_ATTRIBUTES ObjectAttributes
;
375 UNICODE_STRING UnicodeDeviceDirName
;
376 WCHAR NameBuffer
[80];
377 CHAR NameBuffer2
[80];
378 PDEVICE_OBJECT DiskDeviceObject
;
379 PDEVICE_OBJECT PartitionDeviceObject
;
380 PDEVICE_EXTENSION DiskDeviceExtension
; /* defined in class2.h */
381 PDEVICE_EXTENSION PartitionDeviceExtension
; /* defined in class2.h */
382 PDRIVE_LAYOUT_INFORMATION PartitionList
= NULL
;
384 PPARTITION_INFORMATION PartitionEntry
;
386 ULONG PartitionNumber
;
389 DPRINT("DiskClassCreateDeviceObject() called\n");
391 /* Create the harddisk device directory */
393 L
"\\Device\\Harddisk%lu",
395 RtlInitUnicodeString(&UnicodeDeviceDirName
,
397 InitializeObjectAttributes(&ObjectAttributes
,
398 &UnicodeDeviceDirName
,
402 Status
= ZwCreateDirectoryObject(&Handle
,
405 if (!NT_SUCCESS(Status
))
407 DbgPrint("Could not create device dir object\n");
411 /* Claim the disk device */
412 Status
= ScsiClassClaimDevice(PortDeviceObject
,
416 if (!NT_SUCCESS(Status
))
418 DbgPrint("Could not claim disk device\n");
420 ZwMakeTemporaryObject(Handle
);
426 /* Create disk device (Partition 0) */
428 "\\Device\\Harddisk%lu\\Partition0",
431 Status
= ScsiClassCreateDeviceObject(DriverObject
,
436 if (!NT_SUCCESS(Status
))
438 DPRINT1("ScsiClassCreateDeviceObject() failed (Status %x)\n", Status
);
440 /* Release (unclaim) the disk */
441 ScsiClassClaimDevice(PortDeviceObject
,
446 /* Delete the harddisk device directory */
447 ZwMakeTemporaryObject(Handle
);
453 DiskDeviceObject
->Flags
|= DO_DIRECT_IO
;
454 if (((PINQUIRYDATA
)InquiryData
->InquiryData
)->RemovableMedia
)
456 DiskDeviceObject
->Characteristics
|= FILE_REMOVABLE_MEDIA
;
458 DiskDeviceObject
->StackSize
= (CCHAR
)PortDeviceObject
->StackSize
+ 1;
460 if (PortDeviceObject
->AlignmentRequirement
> DiskDeviceObject
->AlignmentRequirement
)
462 DiskDeviceObject
->AlignmentRequirement
= PortDeviceObject
->AlignmentRequirement
;
465 DiskDeviceExtension
= DiskDeviceObject
->DeviceExtension
;
466 DiskDeviceExtension
->LockCount
= 0;
467 DiskDeviceExtension
->DeviceNumber
= DiskNumber
;
468 DiskDeviceExtension
->PortDeviceObject
= PortDeviceObject
;
469 DiskDeviceExtension
->PhysicalDevice
= DiskDeviceObject
;
471 /* FIXME: Not yet! Will cause pointer corruption! */
472 // DiskDeviceExtension->PortCapabilities = PortCapabilities;
474 DiskDeviceExtension
->StartingOffset
.QuadPart
= 0;
475 DiskDeviceExtension
->PortNumber
= (UCHAR
)PortNumber
;
476 DiskDeviceExtension
->PathId
= InquiryData
->PathId
;
477 DiskDeviceExtension
->TargetId
= InquiryData
->TargetId
;
478 DiskDeviceExtension
->Lun
= InquiryData
->Lun
;
480 /* zero-out disk data */
481 DiskData
= (PDISK_DATA
)(DiskDeviceExtension
+ 1);
482 RtlZeroMemory(DiskData
,
485 /* Get disk geometry */
486 DiskDeviceExtension
->DiskGeometry
= ExAllocatePool(NonPagedPool
,
487 sizeof(DISK_GEOMETRY
));
488 if (DiskDeviceExtension
->DiskGeometry
== NULL
)
490 DPRINT1("Failed to allocate geometry buffer!\n");
492 IoDeleteDevice(DiskDeviceObject
);
494 /* Release (unclaim) the disk */
495 ScsiClassClaimDevice(PortDeviceObject
,
500 /* Delete the harddisk device directory */
501 ZwMakeTemporaryObject(Handle
);
504 return(STATUS_INSUFFICIENT_RESOURCES
);
507 /* Read the drive's capacity */
508 Status
= ScsiClassReadDriveCapacity(DiskDeviceObject
);
509 if (!NT_SUCCESS(Status
) &&
510 (DiskDeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
) == 0)
512 DPRINT1("Failed to retrieve drive capacity!\n");
513 return(STATUS_SUCCESS
);
517 /* Clear the verify flag for non-removable media drives. */
518 DiskDeviceObject
->Flags
&= ~DO_VERIFY_VOLUME
;
521 DPRINT("SectorSize: %lu\n", DiskDeviceExtension
->DiskGeometry
->BytesPerSector
);
523 /* Read partition table */
524 Status
= IoReadPartitionTable(DiskDeviceObject
,
525 DiskDeviceExtension
->DiskGeometry
->BytesPerSector
,
529 DPRINT("IoReadPartitionTable(): Status: %lx\n", Status
);
531 if ((!NT_SUCCESS(Status
) || PartitionList
->PartitionCount
== 0) &&
532 DiskDeviceObject
->Characteristics
& FILE_REMOVABLE_MEDIA
)
534 if (!NT_SUCCESS(Status
))
536 /* Drive is not ready. */
537 DPRINT1("Drive not ready\n");
538 DiskData
->DriveNotReady
= TRUE
;
542 ExFreePool(PartitionList
);
545 /* Allocate a partition list for a single entry. */
546 PartitionList
= ExAllocatePool(NonPagedPool
,
547 sizeof(DRIVE_LAYOUT_INFORMATION
));
548 if (PartitionList
!= NULL
)
550 RtlZeroMemory(PartitionList
,
551 sizeof(DRIVE_LAYOUT_INFORMATION
));
552 PartitionList
->PartitionCount
= 1;
554 Status
= STATUS_SUCCESS
;
558 if (NT_SUCCESS(Status
))
560 DPRINT("Read partition table!\n");
562 DPRINT(" Number of partitions: %u\n", PartitionList
->PartitionCount
);
564 for (PartitionNumber
= 0; PartitionNumber
< PartitionList
->PartitionCount
; PartitionNumber
++)
566 PartitionEntry
= &PartitionList
->PartitionEntry
[PartitionNumber
];
568 DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
570 PartitionEntry
->PartitionNumber
,
571 PartitionEntry
->BootIndicator
,
572 PartitionEntry
->PartitionType
,
573 PartitionEntry
->StartingOffset
.QuadPart
/ 512 /*DrvParms.BytesPerSector*/,
574 PartitionEntry
->PartitionLength
.QuadPart
/ 512 /* DrvParms.BytesPerSector*/);
576 /* Create partition device (Partition 0) */
578 "\\Device\\Harddisk%lu\\Partition%lu",
580 PartitionNumber
+ 1);
582 Status
= ScsiClassCreateDeviceObject(DriverObject
,
585 &PartitionDeviceObject
,
587 DPRINT("ScsiClassCreateDeviceObject(): Status %x\n", Status
);
588 if (NT_SUCCESS(Status
))
590 PartitionDeviceObject
->Flags
= DiskDeviceObject
->Flags
;
591 PartitionDeviceObject
->Characteristics
= DiskDeviceObject
->Characteristics
;
592 PartitionDeviceObject
->StackSize
= DiskDeviceObject
->StackSize
;
593 PartitionDeviceObject
->AlignmentRequirement
= DiskDeviceObject
->AlignmentRequirement
;
595 PartitionDeviceExtension
= PartitionDeviceObject
->DeviceExtension
;
596 PartitionDeviceExtension
->LockCount
= 0;
597 PartitionDeviceExtension
->DeviceNumber
= DiskNumber
;
598 PartitionDeviceExtension
->PortDeviceObject
= PortDeviceObject
;
599 PartitionDeviceExtension
->DiskGeometry
= DiskDeviceExtension
->DiskGeometry
;
600 PartitionDeviceExtension
->PhysicalDevice
= DiskDeviceExtension
->PhysicalDevice
;
602 /* FIXME: Not yet! Will cause pointer corruption! */
603 // PartitionDeviceExtension->PortCapabilities = PortCapabilities;
605 PartitionDeviceExtension
->StartingOffset
.QuadPart
=
606 PartitionEntry
->StartingOffset
.QuadPart
;
607 PartitionDeviceExtension
->PartitionLength
.QuadPart
=
608 PartitionEntry
->PartitionLength
.QuadPart
;
609 PartitionDeviceExtension
->PortNumber
= (UCHAR
)PortNumber
;
610 PartitionDeviceExtension
->PathId
= InquiryData
->PathId
;
611 PartitionDeviceExtension
->TargetId
= InquiryData
->TargetId
;
612 PartitionDeviceExtension
->Lun
= InquiryData
->Lun
;
614 DiskData
= (PDISK_DATA
)(PartitionDeviceExtension
+ 1);
615 DiskData
->PartitionType
= PartitionEntry
->PartitionType
;
616 DiskData
->PartitionNumber
= PartitionNumber
+ 1;
617 DiskData
->HiddenSectors
= PartitionEntry
->HiddenSectors
;
618 DiskData
->BootIndicator
= PartitionEntry
->BootIndicator
;
619 DiskData
->DriveNotReady
= FALSE
;
623 DPRINT1("ScsiClassCreateDeviceObject() failed to create partition device object (Status %x)\n", Status
);
632 if (PartitionList
!= NULL
)
633 ExFreePool(PartitionList
);
635 DPRINT("DiskClassCreateDeviceObjects() done\n");
637 return(STATUS_SUCCESS
);
644 // DiskClassDeviceControl
647 // Answer requests for device control calls
653 // Standard dispatch arguments
660 DiskClassDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
663 PDEVICE_EXTENSION DeviceExtension
;
664 PIO_STACK_LOCATION IrpStack
;
665 ULONG ControlCode
, InputLength
, OutputLength
;
670 DPRINT("DiskClassDeviceControl() called!\n");
672 Status
= STATUS_INVALID_DEVICE_REQUEST
;
674 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
675 ControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
676 InputLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
677 OutputLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
678 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
679 DiskData
= (PDISK_DATA
)(DeviceExtension
+ 1);
681 /* A huge switch statement in a Windows program?! who would have thought? */
684 case IOCTL_DISK_GET_DRIVE_GEOMETRY
:
685 DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY\n");
686 if (IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(DISK_GEOMETRY
))
688 Status
= STATUS_INVALID_PARAMETER
;
690 else if (DeviceExtension
->DiskGeometry
== NULL
)
692 DPRINT1("No disk geometry available!\n");
693 Status
= STATUS_NO_SUCH_DEVICE
;
697 PDISK_GEOMETRY Geometry
;
699 Geometry
= (PDISK_GEOMETRY
) Irp
->AssociatedIrp
.SystemBuffer
;
700 RtlMoveMemory(Geometry
,
701 DeviceExtension
->DiskGeometry
,
702 sizeof(DISK_GEOMETRY
));
704 Status
= STATUS_SUCCESS
;
705 Information
= sizeof(DISK_GEOMETRY
);
709 case IOCTL_DISK_GET_PARTITION_INFO
:
710 DPRINT("IOCTL_DISK_GET_PARTITION_INFO\n");
711 if (IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
<
712 sizeof(PARTITION_INFORMATION
))
714 Status
= STATUS_INFO_LENGTH_MISMATCH
;
716 else if (DiskData
->PartitionNumber
== 0)
718 Status
= STATUS_INVALID_DEVICE_REQUEST
;
722 PPARTITION_INFORMATION PartitionInfo
;
724 PartitionInfo
= (PPARTITION_INFORMATION
)Irp
->AssociatedIrp
.SystemBuffer
;
726 PartitionInfo
->PartitionType
= DiskData
->PartitionType
;
727 PartitionInfo
->StartingOffset
= DeviceExtension
->StartingOffset
;
728 PartitionInfo
->PartitionLength
= DeviceExtension
->PartitionLength
;
729 PartitionInfo
->HiddenSectors
= DiskData
->HiddenSectors
;
730 PartitionInfo
->PartitionNumber
= DiskData
->PartitionNumber
;
731 PartitionInfo
->BootIndicator
= DiskData
->BootIndicator
;
732 PartitionInfo
->RewritePartition
= FALSE
;
733 PartitionInfo
->RecognizedPartition
=
734 IsRecognizedPartition(DiskData
->PartitionType
);
736 Status
= STATUS_SUCCESS
;
737 Information
= sizeof(PARTITION_INFORMATION
);
741 case IOCTL_DISK_SET_PARTITION_INFO
:
742 DPRINT1("Unhandled IOCTL_DISK_SET_PARTITION_INFO\n");
743 Status
= STATUS_INVALID_DEVICE_REQUEST
;
747 case IOCTL_DISK_GET_DRIVE_LAYOUT
:
748 if (IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
<
749 sizeof(DRIVE_LAYOUT_INFORMATION
))
751 Status
= STATUS_BUFFER_TOO_SMALL
;
755 PDRIVE_LAYOUT_INFORMATION PartitionList
;
757 Status
= IoReadPartitionTable(DeviceExtension
->PhysicalDevice
,
758 DeviceExtension
->DiskGeometry
->BytesPerSector
,
761 if (NT_SUCCESS(Status
))
765 BufferSize
= FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION
,
767 BufferSize
+= PartitionList
->PartitionCount
* sizeof(PARTITION_INFORMATION
);
769 if (BufferSize
> IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
)
771 Status
= STATUS_BUFFER_TOO_SMALL
;
775 RtlMoveMemory(Irp
->AssociatedIrp
.SystemBuffer
,
778 Status
= STATUS_SUCCESS
;
779 Information
= BufferSize
;
781 ExFreePool(PartitionList
);
786 case IOCTL_DISK_SET_DRIVE_LAYOUT
:
787 case IOCTL_DISK_VERIFY
:
788 case IOCTL_DISK_FORMAT_TRACKS
:
789 case IOCTL_DISK_PERFORMANCE
:
790 case IOCTL_DISK_IS_WRITABLE
:
791 case IOCTL_DISK_LOGGING
:
792 case IOCTL_DISK_FORMAT_TRACKS_EX
:
793 case IOCTL_DISK_HISTOGRAM_STRUCTURE
:
794 case IOCTL_DISK_HISTOGRAM_DATA
:
795 case IOCTL_DISK_HISTOGRAM_RESET
:
796 case IOCTL_DISK_REQUEST_STRUCTURE
:
797 case IOCTL_DISK_REQUEST_DATA
:
799 /* If we get here, something went wrong. inform the requestor */
801 DPRINT1("Unhandled control code: %lx\n", ControlCode
);
802 Status
= STATUS_INVALID_DEVICE_REQUEST
;
807 Irp
->IoStatus
.Status
= Status
;
808 Irp
->IoStatus
.Information
= Information
;
809 IoCompleteRequest(Irp
,
816 /**********************************************************************
818 * DiskClassShutdownFlush
821 * Answer requests for shutdown and flush calls.
828 * Pointer to the device.
838 DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject
,
841 DPRINT("DiskClassShutdownFlush() called!\n");
843 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
844 Irp
->IoStatus
.Information
= 0;
845 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
847 return(STATUS_SUCCESS
);