disk.c
来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 2,016 行 · 第 1/5 页
C
2,016 行
#if 0
CHAR Buffer[256];
ULONG i, j;
UCHAR sum = 0;
memset(Buffer, 0, sizeof(Buffer));
for (i = 0; i < 512; i += 16)
{
for (j = 0; j < 16 && i + j < 512; j++)
{
sprintf(&Buffer[3*j], "%02x ", ((PSENDCMDOUTPARAMS)(SrbIoControl + 1))->bBuffer[i + j]);
sum += ((PSENDCMDOUTPARAMS)(SrbIoControl + 1))->bBuffer[i + j];
}
for (j = 0; j < 16 && i + j < 512; j++)
{
sprintf(&Buffer[3*16 + j], "%c", isprint(((PSENDCMDOUTPARAMS)(SrbIoControl + 1))->bBuffer[i + j]) ? ((PSENDCMDOUTPARAMS)(SrbIoControl + 1))->bBuffer[i + j] : '.');
}
DPRINT1("%04x %s\n", i, Buffer);
}
DPRINT1("Sum %02x\n", sum);
#endif
Information = SrbIoControl->Length;
}
else
{
Information = sizeof(SENDCMDOUTPARAMS) -1;
}
memcpy(Irp->AssociatedIrp.SystemBuffer, InParams, Information);
ExFreePool(SrbIoControl);
break;
}
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
{
WCHAR NameBuffer[80];
PMOUNTDEV_NAME pMountDevName;
ULONG NameLength;
DPRINT("IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n");
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME))
{
Status = STATUS_BUFFER_TOO_SMALL;
Information = 0;
}
else
{
pMountDevName = (PMOUNTDEV_NAME)Irp->AssociatedIrp.SystemBuffer;
swprintf(NameBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
DeviceExtension->DeviceNumber,
((PDISK_DATA)(DeviceExtension + 1))->PartitionNumber);
NameLength = wcslen(NameBuffer) * sizeof(WCHAR);
pMountDevName->NameLength = NameLength;
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + NameLength)
{
Information = sizeof(MOUNTDEV_NAME);
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
RtlCopyMemory(pMountDevName->Name, NameBuffer, NameLength);
Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + NameLength;
Status = STATUS_SUCCESS;
}
}
break;
}
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
{
WCHAR NameBuffer[80];
PMOUNTDEV_UNIQUE_ID pMountDevUniqueId;
ULONG UniqueIdLength;
DPRINT("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n");
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME))
{
Status = STATUS_BUFFER_TOO_SMALL;
Information = 0;
}
else
{
pMountDevUniqueId = (PMOUNTDEV_UNIQUE_ID)Irp->AssociatedIrp.SystemBuffer;
swprintf(NameBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
DeviceExtension->DeviceNumber,
((PDISK_DATA)(DeviceExtension + 1))->PartitionNumber);
UniqueIdLength = wcslen(NameBuffer) * sizeof(WCHAR);
pMountDevUniqueId->UniqueIdLength = UniqueIdLength;
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueIdLength)
{
Information = sizeof(MOUNTDEV_UNIQUE_ID);
Status = STATUS_BUFFER_OVERFLOW;
}
else
{
RtlCopyMemory(pMountDevUniqueId->UniqueId, NameBuffer, UniqueIdLength);
Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + UniqueIdLength;
Status = STATUS_SUCCESS;
}
}
break;
}
default:
/* Call the common device control function */
return(ScsiClassDeviceControl(DeviceObject, Irp));
}
/* Verify the device if the user caused the error */
if (!NT_SUCCESS(Status) && IoIsErrorUserInduced(Status))
{
IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(Status);
}
/**********************************************************************
* NAME EXPORTED
* DiskClassShutdownFlush
*
* DESCRIPTION
* Answer requests for shutdown and flush calls.
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* DeviceObject
* Pointer to the device.
*
* Irp
* Pointer to the IRP
*
* RETURN VALUE
* Status
*/
NTSTATUS STDCALL
DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpStack;
PSCSI_REQUEST_BLOCK Srb;
DPRINT("DiskClassShutdownFlush() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
/* Allocate SRB */
Srb = ExAllocatePool(NonPagedPool,
sizeof(SCSI_REQUEST_BLOCK));
if (Srb == NULL)
{
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
/* Set timeout */
Srb->TimeOutValue = DeviceExtension->TimeOutValue * 4;
/* Flush write cache */
Srb->CdbLength = 10;
Srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
ScsiClassSendSrbSynchronous(DeviceObject,
Srb,
NULL,
0,
TRUE);
/* Get current stack location */
IrpStack = IoGetCurrentIrpStackLocation(Irp);
/* FIXME: Unlock removable media upon shutdown */
/* No retry */
IrpStack->Parameters.Others.Argument4 = (PVOID)0;
/* Send shutdown or flush request to the port driver */
Srb->CdbLength = 0;
if (IrpStack->MajorFunction == IRP_MJ_SHUTDOWN)
Srb->Function = SRB_FUNCTION_SHUTDOWN;
else
Srb->Function = SRB_FUNCTION_FLUSH;
/* Init completion routine */
IoSetCompletionRoutine(Irp,
ScsiClassIoComplete,
Srb,
TRUE,
TRUE,
TRUE);
/* Prepare next stack location for a call to the port driver */
IrpStack = IoGetNextIrpStackLocation(Irp);
IrpStack->MajorFunction = IRP_MJ_SCSI;
IrpStack->Parameters.Scsi.Srb = Srb;
Srb->OriginalRequest = Irp;
/* Call port driver */
return(IoCallDriver(DeviceExtension->PortDeviceObject, Irp));
}
/**********************************************************************
* NAME INTERNAL
* DiskClassUpdatePartitionDeviceObjects
*
* DESCRIPTION
* Deletes, modifies or creates partition device objects.
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* DeviceObject
* Pointer to the device.
*
* Irp
* Pointer to the IRP
*
* RETURN VALUE
* None
*/
static VOID
DiskClassUpdatePartitionDeviceObjects(IN PDEVICE_OBJECT DiskDeviceObject,
IN PIRP Irp)
{
PDRIVE_LAYOUT_INFORMATION PartitionList;
PPARTITION_INFORMATION PartitionEntry;
PDEVICE_EXTENSION DeviceExtension;
PDEVICE_EXTENSION DiskDeviceExtension;
PDISK_DATA DiskData;
ULONG PartitionCount;
ULONG PartitionOrdinal;
ULONG PartitionNumber;
ULONG LastPartitionNumber;
ULONG i;
BOOLEAN Found;
WCHAR NameBuffer[MAX_PATH];
UNICODE_STRING DeviceName;
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
DPRINT("ScsiDiskUpdatePartitionDeviceObjects() called\n");
/* Get partition list */
PartitionList = Irp->AssociatedIrp.SystemBuffer;
/* Round partition count up by 4 */
PartitionCount = ((PartitionList->PartitionCount + 3) / 4) * 4;
/* Remove the partition numbers from the partition list */
for (i = 0; i < PartitionCount; i++)
{
PartitionList->PartitionEntry[i].PartitionNumber = 0;
}
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
/* Traverse on-disk partition list */
LastPartitionNumber = 0;
DeviceExtension = DiskDeviceExtension;
DiskData = (PDISK_DATA)(DeviceExtension + 1);
while (TRUE)
{
DeviceExtension = DiskData->NextPartition;
if (DeviceExtension == NULL)
break;
/* Get disk data */
DiskData = (PDISK_DATA)(DeviceExtension + 1);
/* Update last partition number */
if (DiskData->PartitionNumber > LastPartitionNumber)
LastPartitionNumber = DiskData->PartitionNumber;
/* Ignore unused on-disk partitions */
if (DeviceExtension->PartitionLength.QuadPart == 0ULL)
continue;
Found = FALSE;
PartitionOrdinal = 0;
for (i = 0; i < PartitionCount; i++)
{
/* Get current partition entry */
PartitionEntry = &PartitionList->PartitionEntry[i];
/* Ignore empty (aka unused) or extended partitions */
if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
IsContainerPartition (PartitionEntry->PartitionType))
continue;
PartitionOrdinal++;
/* Check for matching partition start offset and length */
if ((PartitionEntry->StartingOffset.QuadPart !=
DeviceExtension->StartingOffset.QuadPart) ||
(PartitionEntry->PartitionLength.QuadPart !=
DeviceExtension->PartitionLength.QuadPart))
continue;
DPRINT("Found matching partition entry for partition %lu\n",
DiskData->PartitionNumber);
/* Found matching partition */
Found = TRUE;
/* Update partition number in partition list */
PartitionEntry->PartitionNumber = DiskData->PartitionNumber;
break;
}
if (Found == TRUE)
{
/* Get disk data for current partition */
DiskData = (PDISK_DATA)(DeviceExtension + 1);
/* Update partition type if partiton will be rewritten */
if (PartitionEntry->RewritePartition == TRUE)
DiskData->PartitionType = PartitionEntry->PartitionType;
/* Assign new partiton ordinal */
DiskData->PartitionOrdinal = PartitionOrdinal;
DPRINT("Partition ordinal %lu was assigned to partition %lu\n",
DiskData->PartitionOrdinal,
DiskData->PartitionNumber);
}
else
{
/* Delete this partition */
DeviceExtension->PartitionLength.QuadPart = 0ULL;
DPRINT("Deleting partition %lu\n",
DiskData->PartitionNumber);
}
}
/* Traverse partiton list and create new partiton devices */
PartitionOrdinal = 0;
for (i = 0; i < PartitionCount; i++)
{
/* Get current partition entry */
PartitionEntry = &PartitionList->PartitionEntry[i];
/* Ignore empty (aka unused) or extended partitions */
if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
IsContainerPartition (PartitionEntry->PartitionType))
continue;
PartitionOrdinal++;
/* Ignore unchanged partition entries */
if (PartitionEntry->RewritePartition == FALSE)
continue;
/* Check for an unused device object */
PartitionNumber = 0;
DeviceExtension = DiskDeviceExtension;
DiskData = (PDISK_DATA)(DeviceExtension + 1);
while (TRUE)
{
DeviceExtension = DiskData->NextPartition;
if (DeviceExtension == NULL)
break;
/* Get partition disk data */
DiskData = (PDISK_DATA)(DeviceExtension + 1);
/* Found a free (unused) partition (device object) */
if (DeviceExtension->PartitionLength.QuadPart == 0ULL)
{
PartitionNumber = DiskData->PartitionNumber;
break;
}
}
if (PartitionNumber == 0)
{
/* Create a new partition device object */
DPRINT("Create new partition device object\n");
/* Get new partiton number */
LastPartitionNumber++;
PartitionNumber =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?