1 /* $Id: disk.c,v 1.1 2001/07/24 10:21:15 ekohl Exp $
5 // -------------------------------------------------------------------------
13 //#include "partitio.h"
15 #define VERSION "V0.0.1"
18 static NTSTATUS
DiskCreateDevices(VOID
);
19 static BOOLEAN
DiskFindDiskDrives(PDEVICE_OBJECT PortDeviceObject
, ULONG PortNumber
);
26 * Answer requests for Open/Close calls: a null operation
32 * Standard dispatch arguments
38 static NTSTATUS STDCALL
39 DiskOpenClose(IN PDEVICE_OBJECT pDO
,
42 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
43 Irp
->IoStatus
.Information
= FILE_OPENED
;
44 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
46 return STATUS_SUCCESS
;
51 static NTSTATUS STDCALL
52 DiskClassReadWrite(IN PDEVICE_OBJECT pDO
,
55 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
56 Irp
->IoStatus
.Information
= 0;
57 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
59 return STATUS_SUCCESS
;
63 static NTSTATUS STDCALL
64 DiskClassDeviceControl(IN PDEVICE_OBJECT pDO
,
67 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
68 Irp
->IoStatus
.Information
= 0;
69 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
71 return STATUS_SUCCESS
;
75 static NTSTATUS STDCALL
76 DiskClassShutdownFlush(IN PDEVICE_OBJECT pDO
,
79 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
80 Irp
->IoStatus
.Information
= 0;
81 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
83 return STATUS_SUCCESS
;
90 // This function initializes the driver, locates and claims
91 // hardware resources, and creates various NT objects needed
92 // to process I/O requests.
98 // IN PDRIVER_OBJECT DriverObject System allocated Driver Object
100 // IN PUNICODE_STRING RegistryPath Name of registry driver service
107 DriverEntry(IN PDRIVER_OBJECT DriverObject
,
108 IN PUNICODE_STRING RegistryPath
)
112 DbgPrint("Disk Class Driver %s\n", VERSION
);
114 /* Export other driver entry points... */
115 // DriverObject->DriverStartIo = IDEStartIo;
116 // DriverObject->MajorFunction[IRP_MJ_CREATE] = DiskClassOpenClose;
117 // DriverObject->MajorFunction[IRP_MJ_CLOSE] = DiskClassOpenClose;
118 DriverObject
->MajorFunction
[IRP_MJ_READ
] = DiskClassReadWrite
;
119 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = DiskClassReadWrite
;
120 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = DiskClassDeviceControl
;
121 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = DiskClassShutdownFlush
;
122 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = DiskClassShutdownFlush
;
124 Status
= DiskCreateDevices();
125 DPRINT("Status 0x%08X\n", Status
);
127 DPRINT("Returning from DriverEntry\n");
128 return STATUS_SUCCESS
;
134 DiskCreateDevices(VOID
)
136 WCHAR NameBuffer
[80];
137 UNICODE_STRING PortName
;
138 ULONG PortNumber
= 0;
139 PDEVICE_OBJECT PortDeviceObject
;
140 PFILE_OBJECT FileObject
;
141 BOOLEAN DiskFound
= FALSE
;
144 DPRINT1("DiskCreateDevices() called.\n");
146 /* look for ScsiPortX scsi port devices */
150 L
"\\Device\\ScsiPort%ld",
152 RtlInitUnicodeString(&PortName
,
154 DPRINT1("Checking scsi port %ld\n", PortNumber
);
155 Status
= IoGetDeviceObjectPointer(&PortName
,
156 FILE_READ_ATTRIBUTES
,
159 DPRINT1("Status 0x%08lX\n", Status
);
160 if (NT_SUCCESS(Status
))
162 DPRINT1("ScsiPort%ld found.\n", PortNumber
);
164 /* Check scsi port for attached disk drives */
165 DiskFound
= DiskFindDiskDrives(PortDeviceObject
, PortNumber
);
169 while (NT_SUCCESS(Status
));
171 return(STATUS_SUCCESS
);
176 DiskFindDiskDrives(PDEVICE_OBJECT PortDeviceObject
,
179 DPRINT1("DiskFindDiskDevices() called.\n");
187 // Creates a device by calling IoCreateDevice and a sylbolic link for Win32
193 // IN PDRIVER_OBJECT DriverObject The system supplied driver object
194 // OUT PDEVICE_OBJECT *DeviceObject The created device object
195 // IN PCONTROLLER_OBJECT ControllerObject The Controller for the device
196 // IN BOOLEAN LBASupported Does the drive support LBA addressing?
197 // IN BOOLEAN DMASupported Does the drive support DMA?
198 // IN int SectorsPerLogCyl Sectors per cylinder
199 // IN int SectorsPerLogTrk Sectors per track
200 // IN DWORD Offset First valid sector for this device
201 // IN DWORD Size Count of valid sectors for this device
208 IDECreateDevice(IN PDRIVER_OBJECT DriverObject
,
209 OUT PDEVICE_OBJECT
*DeviceObject
,
210 IN PCONTROLLER_OBJECT ControllerObject
,
213 IN ULONG PartitionNumber
,
214 IN PIDE_DRIVE_IDENTIFY DrvParms
,
218 WCHAR NameBuffer
[IDE_MAX_NAME_LENGTH
];
219 WCHAR ArcNameBuffer
[IDE_MAX_NAME_LENGTH
+ 15];
220 UNICODE_STRING DeviceName
;
221 UNICODE_STRING ArcName
;
223 PIDE_DEVICE_EXTENSION DeviceExtension
;
225 // Create a unicode device name
227 L
"\\Device\\Harddisk%d\\Partition%d",
230 RtlInitUnicodeString(&DeviceName
,
234 RC
= IoCreateDevice(DriverObject
, sizeof(IDE_DEVICE_EXTENSION
),
235 &DeviceName
, FILE_DEVICE_DISK
, 0, TRUE
, DeviceObject
);
238 DPRINT("IoCreateDevice call failed\n",0);
242 // Set the buffering strategy here...
243 (*DeviceObject
)->Flags
|= DO_DIRECT_IO
;
244 (*DeviceObject
)->AlignmentRequirement
= FILE_WORD_ALIGNMENT
;
246 // Fill out Device extension data
247 DeviceExtension
= (PIDE_DEVICE_EXTENSION
) (*DeviceObject
)->DeviceExtension
;
248 DeviceExtension
->DeviceObject
= (*DeviceObject
);
249 DeviceExtension
->ControllerObject
= ControllerObject
;
250 DeviceExtension
->UnitNumber
= UnitNumber
;
251 DeviceExtension
->LBASupported
=
252 (DrvParms
->Capabilities
& IDE_DRID_LBA_SUPPORTED
) ? 1 : 0;
253 DeviceExtension
->DMASupported
=
254 (DrvParms
->Capabilities
& IDE_DRID_DMA_SUPPORTED
) ? 1 : 0;
255 // FIXME: deal with bizarre sector sizes
256 DeviceExtension
->BytesPerSector
= 512 /* DrvParms->BytesPerSector */;
257 DeviceExtension
->SectorsPerLogCyl
= DrvParms
->LogicalHeads
*
258 DrvParms
->SectorsPerTrack
;
259 DeviceExtension
->SectorsPerLogTrk
= DrvParms
->SectorsPerTrack
;
260 DeviceExtension
->LogicalHeads
= DrvParms
->LogicalHeads
;
261 DeviceExtension
->Offset
= Offset
;
262 DeviceExtension
->Size
= Size
;
263 DPRINT("%wZ: offset %d size %d \n",
265 DeviceExtension
->Offset
,
266 DeviceExtension
->Size
);
268 // Initialize the DPC object here
269 IoInitializeDpcRequest(*DeviceObject
, IDEDpcForIsr
);
271 if (PartitionNumber
!= 0)
273 DbgPrint("%wZ %dMB\n", &DeviceName
, Size
/ 2048);
276 /* assign arc name */
277 if (PartitionNumber
== 0)
279 swprintf(ArcNameBuffer
,
280 L
"\\ArcName\\multi(0)disk(0)rdisk(%d)",
285 swprintf(ArcNameBuffer
,
286 L
"\\ArcName\\multi(0)disk(0)rdisk(%d)partition(%d)",
290 RtlInitUnicodeString (&ArcName
,
292 DPRINT("%wZ ==> %wZ\n", &ArcName
, &DeviceName
);
293 RC
= IoAssignArcName (&ArcName
,
297 DPRINT("IoAssignArcName (%wZ) failed (Status %x)\n",
309 // IDEDispatchDeviceControl
312 // Answer requests for device control calls
318 // Standard dispatch arguments
324 static NTSTATUS STDCALL
325 IDEDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject
,
329 ULONG ControlCode
, InputLength
, OutputLength
;
330 PIO_STACK_LOCATION IrpStack
;
331 PIDE_DEVICE_EXTENSION DeviceExtension
;
334 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
335 ControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
336 InputLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
337 OutputLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
338 DeviceExtension
= (PIDE_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
340 // A huge switch statement in a Windows program?! who would have thought?
343 case IOCTL_DISK_GET_DRIVE_GEOMETRY
:
344 if (IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(DISK_GEOMETRY
))
346 Irp
->IoStatus
.Status
= STATUS_INVALID_PARAMETER
;
350 PDISK_GEOMETRY Geometry
;
352 Geometry
= (PDISK_GEOMETRY
) Irp
->AssociatedIrp
.SystemBuffer
;
353 Geometry
->MediaType
= FixedMedia
;
354 // FIXME: should report for RawDevice even on partition
355 Geometry
->Cylinders
.QuadPart
= DeviceExtension
->Size
/
356 DeviceExtension
->SectorsPerLogCyl
;
357 Geometry
->TracksPerCylinder
= DeviceExtension
->SectorsPerLogTrk
/
358 DeviceExtension
->SectorsPerLogCyl
;
359 Geometry
->SectorsPerTrack
= DeviceExtension
->SectorsPerLogTrk
;
360 Geometry
->BytesPerSector
= DeviceExtension
->BytesPerSector
;
362 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
363 Irp
->IoStatus
.Information
= sizeof(DISK_GEOMETRY
);
367 case IOCTL_DISK_GET_PARTITION_INFO
:
368 case IOCTL_DISK_SET_PARTITION_INFO
:
369 case IOCTL_DISK_GET_DRIVE_LAYOUT
:
370 case IOCTL_DISK_SET_DRIVE_LAYOUT
:
371 case IOCTL_DISK_VERIFY
:
372 case IOCTL_DISK_FORMAT_TRACKS
:
373 case IOCTL_DISK_PERFORMANCE
:
374 case IOCTL_DISK_IS_WRITABLE
:
375 case IOCTL_DISK_LOGGING
:
376 case IOCTL_DISK_FORMAT_TRACKS_EX
:
377 case IOCTL_DISK_HISTOGRAM_STRUCTURE
:
378 case IOCTL_DISK_HISTOGRAM_DATA
:
379 case IOCTL_DISK_HISTOGRAM_RESET
:
380 case IOCTL_DISK_REQUEST_STRUCTURE
:
381 case IOCTL_DISK_REQUEST_DATA
:
383 // If we get here, something went wrong. inform the requestor
385 RC
= STATUS_INVALID_DEVICE_REQUEST
;
386 Irp
->IoStatus
.Status
= RC
;
387 Irp
->IoStatus
.Information
= 0;
391 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);