📄 disk.c
字号:
for (i = 0; DiskMediaTypes[i].VendorId != NULL; i++) {
mediaListEntry = &DiskMediaTypes[i];
if (strncmp(mediaListEntry->VendorId,vendorId,strlen(mediaListEntry->VendorId))) {
continue;
}
if ((mediaListEntry->ProductId != NULL) &&
strncmp(mediaListEntry->ProductId, productId, strlen(mediaListEntry->ProductId))) {
continue;
}
if ((mediaListEntry->Revision != NULL) &&
strncmp(mediaListEntry->Revision, productRevision, strlen(mediaListEntry->Revision))) {
continue;
}
deviceMatched = TRUE;
mediaTypes->DeviceType = FILE_DEVICE_DISK;
mediaTypes->MediaInfoCount = mediaListEntry->NumberOfTypes;
//
// Ensure that buffer is large enough.
//
sizeNeeded = FIELD_OFFSET(GET_MEDIA_TYPES, MediaInfo[0]) +
(mediaListEntry->NumberOfTypes *
sizeof(DEVICE_MEDIA_INFO)
);
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeNeeded) {
//
// Buffer too small
//
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
for (j = 0; j < mediaListEntry->NumberOfTypes; j++) {
mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = mediaListEntry->NumberOfSides;
//
// Set the type.
//
mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = mediaListEntry->MediaTypes[j];
if (mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType == MO_5_WO) {
mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_WRITE_ONCE;
} else {
mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
}
//
// Status will either be success, if media is present, or no media.
// It would be optimal to base from density code and medium type, but not all devices
// have values for these fields.
//
if (MediaPresent) {
//
// The usage of MediumType and DensityCode is device specific, so this may need
// to be extended to further key off of product/vendor ids.
// Currently, the MO units are the only devices that return this information.
//
if (MediumType == 2) {
currentMedia = MO_5_WO;
} else if (MediumType == 3) {
currentMedia = MO_5_RW;
if (DensityCode == 0x87) {
//
// Indicate that the pinnacle 4.6 G media
// is present. Other density codes will default to normal
// RW MO media.
//
currentMedia = PINNACLE_APEX_5_RW;
}
} else {
currentMedia = 0;
}
if (currentMedia) {
if (mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType == (STORAGE_MEDIA_TYPE)currentMedia) {
SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
}
} else {
SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
}
}
if (!IsWritable) {
SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_WRITE_PROTECTED);
}
//
// Advance to next entry.
//
mediaInfo++;
}
}
if (!deviceMatched) {
DebugPrint((1,
"DiskDetermineMediaTypes: Unknown device. Vendor: %s Product: %s Revision: %s\n",
vendorId,
productId,
productRevision));
//
// Build an entry for unknown.
//
mediaTypes->DeviceType = FILE_DEVICE_DISK;
mediaTypes->MediaInfoCount = 1;
mediaInfo->DeviceSpecific.RemovableDiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaType = RemovableMedia;
mediaInfo->DeviceSpecific.RemovableDiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
mediaInfo->DeviceSpecific.RemovableDiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
mediaInfo->DeviceSpecific.RemovableDiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics = MEDIA_READ_WRITE;
if (MediaPresent) {
SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_CURRENTLY_MOUNTED);
}
if (!IsWritable) {
SET_FLAG(mediaInfo->DeviceSpecific.RemovableDiskInfo.MediaCharacteristics, MEDIA_WRITE_PROTECTED);
}
}
}
Irp->IoStatus.Information =
FIELD_OFFSET(GET_MEDIA_TYPES, MediaInfo[0]) +
(mediaTypes->MediaInfoCount * sizeof(DEVICE_MEDIA_INFO));
return STATUS_SUCCESS;
}
NTSTATUS
DiskDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
/*++
Routine Description:
I/O system entry for device controls to SCSI disks.
Arguments:
Fdo - Pointer to functional device object created by system.
Irp - IRP involved.
Return Value:
Status is returned.
--*/
#define SendToFdo(Dev, Irp, Rval) { \
PCOMMON_DEVICE_EXTENSION ce = Dev->DeviceExtension; \
ASSERT_PDO(Dev); \
IoCopyCurrentIrpStackLocationToNext(Irp); \
Rval = IoCallDriver(ce->LowerDeviceObject, Irp); \
}
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
PPHYSICAL_DEVICE_EXTENSION pdoExtension = DeviceObject->DeviceExtension;
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
PSCSI_REQUEST_BLOCK srb;
PCDB cdb;
PMODE_PARAMETER_HEADER modeData;
PIRP irp2;
ULONG length;
NTSTATUS status = STATUS_SUCCESS;
KEVENT event;
IO_STATUS_BLOCK ioStatus = { 0 };
BOOLEAN b = FALSE;
srb = ExAllocatePoolWithTag(NonPagedPool,
SCSI_REQUEST_BLOCK_SIZE,
DISK_TAG_SRB);
Irp->IoStatus.Information = 0;
if (srb == NULL) {
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest(DeviceObject, Irp, IO_NO_INCREMENT);
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(srb, SCSI_REQUEST_BLOCK_SIZE);
cdb = (PCDB)srb->Cdb;
switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_DISK_GET_CACHE_INFORMATION:
b = TRUE;
case IOCTL_DISK_SET_CACHE_INFORMATION: {
BOOLEAN getCaching = b;
PDISK_CACHE_INFORMATION cacheInfo = Irp->AssociatedIrp.SystemBuffer;
if(!commonExtension->IsFdo) {
ClassReleaseRemoveLock(DeviceObject, Irp);
ExFreePool(srb);
SendToFdo(DeviceObject, Irp, status);
return status;
}
//
// Validate the request.
//
if((getCaching) &&
(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(DISK_CACHE_INFORMATION))
) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
if ((!getCaching) &&
(irpStack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(DISK_CACHE_INFORMATION))
) {
status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
ASSERT(Irp->AssociatedIrp.SystemBuffer != NULL);
if (getCaching) {
status = DiskGetCacheInformation(fdoExtension, cacheInfo);
if (NT_SUCCESS(status)) {
Irp->IoStatus.Information = sizeof(DISK_CACHE_INFORMATION);
}
} else {
status = DiskSetCacheInformation(fdoExtension, cacheInfo);
//
// Save away the user-defined override in our extension and the registry
//
if (cacheInfo->WriteCacheEnabled)
{
diskData->WriteCacheOverride = DiskWriteCacheEnable;
}
else
{
diskData->WriteCacheOverride = DiskWriteCacheDisable;
}
ClassSetDeviceParameter(fdoExtension, DiskDeviceParameterSubkey, DiskDeviceUserWriteCacheSetting, diskData->WriteCacheOverride);
DiskLogCacheInformation(fdoExtension, cacheInfo, status);
}
break;
}
case IOCTL_DISK_GET_CACHE_SETTING: {
if (!commonExtension->IsFdo) {
ClassReleaseRemoveLock(DeviceObject, Irp);
ExFreePool(srb);
SendToFdo(DeviceObject, Irp, status);
return status;
}
status = DiskIoctlGetCacheSetting(fdoExtension, Irp);
break;
}
case IOCTL_DISK_SET_CACHE_SETTING: {
if (!commonExtension->IsFdo)
{
ClassReleaseRemoveLock(DeviceObject, Irp);
ExFreePool(srb);
SendToFdo(DeviceObject, Irp, status);
return status;
}
status = DiskIoctlSetCacheSetting(fdoExtension, Irp);
break;
}
case SMART_GET_VERSION: {
PUCHAR buffer;
PSRB_IO_CONTROL srbControl;
PGETVERSIONINPARAMS versionParams;
if(!commonExtension->IsFdo) {
ClassReleaseRemoveLock(DeviceObject, Irp);
ExFreePool(srb);
SendToFdo(DeviceObject, Irp, status);
return status;
}
if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(GETVERSIONINPARAMS)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
srbControl = ExAllocatePoolWithTag(NonPagedPool,
sizeof(SRB_IO_CONTROL) +
sizeof(GETVERSIONINPARAMS),
DISK_TAG_SMART);
if (!srbControl) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlZeroMemory(srbControl,
sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS)
);
//
// fill in srbControl fields
//
srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
srbControl->Timeout = fdoExtension->TimeOutValue;
srbControl->Length = sizeof(GETVERSIONINPARAMS);
srbControl->ControlCode = IOCTL_SCSI_MINIPORT_SMART_VERSION;
//
// Point to the 'buffer' portion of the SRB_CONTROL
//
buffer = (PUCHAR)srbControl;
(ULONG_PTR)buffer += srbControl->HeaderLength;
//
// Ensure correct target is set in the cmd parameters.
//
versionParams = (PGETVERSIONINPARAMS)buffer;
versionParams->bIDEDeviceMap = diskData->ScsiAddress.TargetId;
ClassSendDeviceIoControlSynchronous(
IOCTL_SCSI_MINIPORT,
commonExtension->LowerDeviceObject,
srbControl,
sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
FALSE,
&ioStatus);
status = ioStatus.Status;
//
// If successful, copy the data received into the output buffer.
// This should only fail in the event that the IDE driver is older
// than this driver.
//
if (NT_SUCCESS(status)) {
buffer = (PUCHAR)srbControl;
(ULONG_PTR)buffer += srbControl->HeaderLength;
RtlMoveMemory (Irp->AssociatedIrp.SystemBuffer, buffer,
sizeof(GETVERSIONINPARAMS));
Irp->IoStatus.Information = sizeof(GETVERSIONINPARAMS);
}
ExFreePool(srbControl);
break;
}
case SMART_RCV_DRIVE_DATA: {
PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
ULONG controlCode = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -