📄 init.c
字号:
// Read partition table
//
partitionList = NULL;
ntStatus = IoReadPartitionTable(devExt->DeviceObject,
ConfigData->Disk.BytesPerSector,
TRUE,
&partitionList);
//
// Check on the status of IoReadPartitionTable()
//
if (!NT_SUCCESS(ntStatus)) {
//
// IoReadPartitionTable() failed, but force success so we don't
// unload since we still have partition 0 to support.
//
DbgPrint("InitializeDisk: Couldn't read the partition table - status %x\n",ntStatus);
ntStatus = STATUS_SUCCESS;
} else {
//
// IoReadPartitionTable() didn't return error, so initialize the
// partition.
//
partitionPointer = &devExt->NextPartition;
//
// we're assuming a single partition
//
partitionNumber = 0;
//
// Create the device, with a UNICODE name such as
// \\Device\Harddisk0\Partition1
//
sprintf(partitionNameBuffer,
"\\Device\\Harddisk%d\\Partition%d",
*(ConfigData->HardDiskCount),
partitionNumber + 1);
//
// convert the Ansi string into UNICODE
//
RtlInitString (&partitionNameString, partitionNameBuffer);
ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
&partitionNameString,
TRUE);
//
// if we can't get a UNICODE string, we've failed
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the partition 1"
" partition objects\n");
goto InitializeDiskExit;
}
//
// Create the device for this partition
//
ntStatus = IoCreateDevice(DriverObject,
sizeof(PARTITION_DATA),
&unicodeString,
FILE_DEVICE_DISK,
0,
FALSE,
&partitionObject);
//
// Free the UNICODE string no matter the success of IoCreateDevice
// (so that we don't forget to later on)
//
RtlFreeUnicodeString(&unicodeString);
//
// Now check the success of IoCreateDevice
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the partition 1"
" partition devices\n");
goto InitializeDiskExit;
}
//
// Now initialize the partition object and data.
//
partitionObject->Flags |= DO_DIRECT_IO;
partitionData = partitionObject->DeviceExtension;
partitionData->PartitionOrdinal =
partitionData->Pi.PartitionNumber = partitionNumber + 1;
partitionData->Pi.PartitionType =
partitionList->PartitionEntry[partitionNumber].PartitionType;
partitionData->Pi.BootIndicator =
partitionList->PartitionEntry[partitionNumber].BootIndicator;
partitionData->Pi.StartingOffset =
partitionList->PartitionEntry[partitionNumber].StartingOffset;
partitionData->Pi.PartitionLength =
partitionList->PartitionEntry[partitionNumber].PartitionLength;
partitionData->Pi.HiddenSectors =
partitionList->PartitionEntry[partitionNumber].HiddenSectors;
partitionData->Partition0 = devExt;
partitionData->NextPartition = NULL;
*partitionPointer = partitionObject;
partitionPointer = &partitionData->NextPartition;
}
InitializeDiskExit:
//
// We now check on the overall status as we may have reached here
// through a "goto"
//
if (!NT_SUCCESS(ntStatus)) {
//
// Delete everything that this routine has allocated.
//
// First the chain of partition objects
//
if (devExt != NULL)
{
nextPartition = devExt->NextPartition;
while (nextPartition != NULL)
{
partitionObject = nextPartition;
partitionData =
(PPARTITION_DATA)(partitionObject->DeviceExtension);
nextPartition = partitionData->NextPartition;
IoDeleteDevice(partitionObject);
}
}
//
// delete the disk device object
//
if (deviceObject != NULL)
{
IoDeleteDevice(deviceObject);
}
//
// delete the object directory. Since it was temporary, all
// we have to do is close this single reference
//
if (handle != NULL)
{
ZwClose(handle);
}
}
//
// Delete the buffer allocated for the partition list.
//
if (partitionList != NULL)
{
ExFreePool(partitionList);
}
//
// and return our final status
//
return ntStatus;
}
///////////////////////////////////////////////////////////////////////////////
//
// ReportUsage
//
// This routine builds a resource list and calls IoReportResourceUsage()
//
// INPUTS:
//
// ConfigData - pointer to the configuration data
// DriverObject - pointer to our driver object
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// TRUE if no conflict was reported, otherwise FALSE
//
// IRQL:
//
// IRQL_PASSIVE_LEVEL
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
static BOOLEAN
ReportUsage(IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData)
{
ULONG size;
ULONG numDesc;
PCM_RESOURCE_LIST resourceList;
PCM_FULL_RESOURCE_DESCRIPTOR nextDesc;
PCM_PARTIAL_RESOURCE_DESCRIPTOR partial;
BOOLEAN conflictDetected;
//
// determine the size of the resource list
//
size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
//
// The full resource descriptor already contains one
// partial. Make room for two more.
//
// It will hold the irq "prd", the controller "csr" "prd", and
// the controller port "prd".
//
size += 2*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
numDesc = 1;
//
// Now we increment the length of the resource list by field offset
// of the first frd. This will give us the length of what preceeds
// the first frd in the resource list.
//
size += FIELD_OFFSET(CM_RESOURCE_LIST, List[0]);
resourceList = ExAllocatePool(PagedPool, size);
if (!resourceList) {
return FALSE;
}
//
// Zero out the field
//
RtlZeroMemory(resourceList, size);
//
// set the count in the resource list
//
resourceList->Count = numDesc;
//
// get a pointer to the first descriptor off the list
//
nextDesc = &resourceList->List[0];
//
// set the interfae and bus information
//
nextDesc->InterfaceType = ConfigData->InterfaceType;
nextDesc->BusNumber = ConfigData->BusNumber;
//
// We only report 3 items
//
nextDesc->PartialResourceList.Count = 3;
partial = &nextDesc->PartialResourceList.PartialDescriptors[0];
//
// fill in the ControllerBase information
//
partial->Type = CmResourceTypePort;
partial->ShareDisposition = CmResourceShareDriverExclusive;
partial->Flags = CM_RESOURCE_PORT_IO;
partial->u.Port.Start = ConfigData->OriginalControllerBaseAddress;
partial->u.Port.Length = ConfigData->RangeOfControllerBase;
partial++;
//
// fill in the ControlPort information
//
partial->Type = CmResourceTypePort;
partial->ShareDisposition = CmResourceShareDriverExclusive;
partial->Flags = CM_RESOURCE_PORT_IO;
partial->u.Port.Start = ConfigData->OriginalControlPortAddress;
partial->u.Port.Length = ConfigData->RangeOfControlPort;
partial++;
//
// fill in the IRQL information
//
partial->Type = CmResourceTypeInterrupt;
partial->u.Interrupt.Level = ConfigData->OriginalControllerIrql;
partial->u.Interrupt.Vector = ConfigData->OriginalControllerVector;
partial->ShareDisposition = CmResourceShareDriverExclusive;
partial->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
//
// report the information to the I/O Manager
//
IoReportResourceUsage(NULL,
DriverObject,
resourceList,
size,
NULL,
NULL,
0,
FALSE,
&conflictDetected);
//
// cleanup and return
//
ExFreePool(resourceList);
//
// Note that we return the inverse of the return status of
// IoReportResourceUsage
//
return !conflictDetected;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -