📄 init.c
字号:
if (controllerData->InterruptObject != NULL)
{
IoDisconnectInterrupt(controllerData->InterruptObject);
}
//
// and now free the allocated data
//
ExFreePool(controllerData);
}
return ntStatus;
}
///////////////////////////////////////////////////////////////////////////////
//
// InitializeDisk
//
// This routine initializes the disk
//
// INPUTS:
//
// ConfigData - pointer to the configuration data
// DriverObject - pointer to our driver object
// ControllerData - pointer to CONTROLLER_DATA data
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// STATUS_SUCCESS if the disk initializes, otherwise an error code
//
// IRQL:
//
// IRQL_PASSIVE_LEVEL
//
// NOTES:
//
// This assumes:
//
// - controller has been initialized and/or reset
// - interrupts have been enabled
//
// Here we:
//
// - create a directory for the device object
// - allocates and initializes device object for the disk
// - set the drive parameters
// - reads the partition table
// - allocates/initializes a partition object
//
//
///////////////////////////////////////////////////////////////////////////////
static NTSTATUS
InitializeDisk(IN PDRIVER_OBJECT DriverObject,
IN PCONFIG_DATA ConfigData,
IN OUT PCONTROLLER_DATA ControllerData)
{
UCHAR partitionNameBuffer[256]; // temp Ansi buffer
STRING partitionNameString; // temp Ansi string
UNICODE_STRING unicodeString; // temp UNICODE string
PDRIVE_LAYOUT_INFORMATION partitionList; // for the partition table
OBJECT_ATTRIBUTES objectAttributes; // for the directory object
HANDLE handle = NULL; // handle of directory object
PDEVICE_OBJECT deviceObject = NULL; // ptr to part 0 device object
PDEVICE_OBJECT partitionObject; // ptr to a part x device object
PDEVICE_OBJECT nextPartition; // ptr for walking chain
PDEVICE_OBJECT *partitionPointer;
PIDE_DEV_EXT devExt = NULL; // ptr to device extension
PPARTITION_DATA partitionData; // ptr to partition extension
NTSTATUS ntStatus;
ULONG partitionNumber;
//
// Generate a directory object for the partition
//
sprintf(partitionNameBuffer,"\\Device\\Harddisk%d",*(ConfigData->HardDiskCount));
//
// initialize the STRING structure with the constructed
// partitionNamebuffer in preparation to the conversion of this
// Ansi string to UNICODE
//
RtlInitString(&partitionNameString, partitionNameBuffer);
//
// convert the Ansi string to UNICODE
//
ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
&partitionNameString,
TRUE);
//
// if we couldn't convert the string, then we've failed
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the unicode device name\n");
goto InitializeDiskExit;
}
//
// Initialzie the object attributes structure for a subsequent Zw
// call to create the directory
//
InitializeObjectAttributes(&objectAttributes,
&unicodeString,
OBJ_PERMANENT,
NULL,
NULL);
//
// Create the directory
//
ntStatus = ZwCreateDirectoryObject(&handle,
DIRECTORY_ALL_ACCESS,
&objectAttributes);
//
// Since we're done with the UNICODE string (no matter what the
// results of ZwCreateDirectoryObject()), we free the structure
// now so we don't forget later on.
//
RtlFreeUnicodeString(&unicodeString);
//
// If we fail on the ZwCreateDirectoryObject(), then we've failed
// initialization and we need to report back
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the directory object\n");
goto InitializeDiskExit;
}
//
// Alter the attributes for the directory to be temporary, so that
// if/when the handle count on the object goes to zero, it will be
// deleted
//
ZwMakeTemporaryObject(handle);
//
// create partition 0 object
//
sprintf(partitionNameBuffer,
"\\Device\\Harddisk%d\\Partition0",
*(ConfigData->HardDiskCount));
//
// setup the ansi string for the UNICODE conversion
//
RtlInitString(&partitionNameString, partitionNameBuffer);
ntStatus = RtlAnsiStringToUnicodeString(&unicodeString,
&partitionNameString,
TRUE);
//
// fail initialization if we can't get the UNICODE string
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the partition unicode name\n");
goto InitializeDiskExit;
}
//
// Create our disk device
//
ntStatus = IoCreateDevice(DriverObject,
sizeof(IDE_DEV_EXT),
&unicodeString,
FILE_DEVICE_DISK,
0,
FALSE,
&deviceObject);
//
// Again, we're done with the UNICODE string no matter the success
// of IoCreateDevice(), so free it now
//
RtlFreeUnicodeString(&unicodeString);
//
// Check on the success of IoCreateDevice()
//
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("InitializeDisk: Couldn't create the device object - status %x\n",
ntStatus);
goto InitializeDiskExit;
}
//
// Initialize partition 0 device object and extension data. Store pointer
// to controller extension in partition 0's extension.
//
deviceObject->Flags |= DO_DIRECT_IO;
deviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
devExt = (PIDE_DEV_EXT)(deviceObject->DeviceExtension);
devExt->DiskNumber = *ConfigData->HardDiskCount;
devExt->ControllerData = ControllerData;
devExt->Partition0 = devExt;
devExt->DeviceObject = deviceObject;
devExt->DirectoryHandle = handle;
devExt->PacketIsBeingRetried = FALSE;
//
// Set the device unit. We must examine DiskNum for the case
// where the controller says this is drive 2, but we were unable to
// initialize the first drive.
//
devExt->DeviceUnit = DRIVE_1;
//
// Fill in device-specific numbers from IdeGetDataConfig
//
devExt->PretendNumberOfCylinders = ConfigData->Disk.PretendNumberOfCylinders;
devExt->PretendTracksPerCylinder = ConfigData->Disk.PretendTracksPerCylinder;
devExt->PretendSectorsPerTrack = ConfigData->Disk.PretendSectorsPerTrack;
devExt->NumberOfCylinders = ConfigData->Disk.NumberOfCylinders;
devExt->TracksPerCylinder = ConfigData->Disk.TracksPerCylinder;
devExt->SectorsPerTrack = ConfigData->Disk.SectorsPerTrack;
devExt->BytesPerSector = ConfigData->Disk.BytesPerSector;
devExt->BytesPerInterrupt = ConfigData->Disk.BytesPerInterrupt;
devExt->WritePrecomp = ConfigData->Disk.WritePrecomp;
devExt->ReadCommand = ConfigData->Disk.ReadCommand;
devExt->WriteCommand = ConfigData->Disk.WriteCommand;
devExt->VerifyCommand = ConfigData->Disk.VerifyCommand;
DbgPrint(
"InitializeDisk: Geometry:\n"
" Appa Cyl: %x\n"
" Appa Hea: %x\n"
" Appa Sec: %x\n"
" Cyl: %x\n"
" Hea: %x\n"
" Sec: %x\n",
devExt->PretendNumberOfCylinders,
devExt->PretendTracksPerCylinder,
devExt->PretendSectorsPerTrack,
devExt->NumberOfCylinders,
devExt->TracksPerCylinder,
devExt->SectorsPerTrack);
//
// Determine the size of partition 0 (the whole disk).
//
devExt->Pi.StartingOffset.QuadPart = 0;
devExt->Pi.PartitionLength.QuadPart =
(UInt32x32To64(devExt->SectorsPerTrack, devExt->BytesPerSector) *
devExt->NumberOfCylinders) *
devExt->TracksPerCylinder;
ASSERT(devExt->BytesPerSector == 512);
//
// Byte to sector number conversion
//
devExt->ByteShiftToSector = 9;
//
// Initialize DPC
//
IoInitializeDpcRequest(deviceObject, IdeDPC);
//
// Give the controller some time to settle down after reset.
//
IdeWaitControllerReady(ControllerData, 20, 150000);
//
// First we'll set up the disk so that it doesn't revert to power
// on defaults after a controller reset. Then we'll set it up
// so that the write cache is disabled.
//
ControllerData->DeviceObject = devExt->DeviceObject;
//
// Select the right drive.
//
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + DRIVE_HEAD_REGISTER,
devExt->DeviceUnit);
//
// Disable the reverting to power on.
//
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + WRITE_PRECOMP_REGISTER,
0x66);
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + COMMAND_REGISTER,
0xef);
//
// wait for the controller to catch its breath
//
IdeWaitControllerReady(ControllerData, 10, 15000);
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + DRIVE_HEAD_REGISTER,
devExt->DeviceUnit);
//
// Set the drive parameters. Note that this will generate an
// interrupt, but we don't have to worry about it.
//
ControllerData->DeviceObject = devExt->DeviceObject;
WRITE_PORT_UCHAR( ControllerData->ControllerAddress + DRIVE_HEAD_REGISTER,
(UCHAR)(devExt->DeviceUnit | (devExt->TracksPerCylinder - 1)));
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + SECTOR_COUNT_REGISTER,
(UCHAR)(devExt->SectorsPerTrack));
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + COMMAND_REGISTER,
SET_DRIVE_PARAMETERS_COMMAND);
//
// Wait for the controller to be ready before we read the table
//
IdeWaitControllerReady(ControllerData, 20, 150000);
//
// Now recalibrate the drive.
//
ControllerData->DeviceObject = devExt->DeviceObject;
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + DRIVE_HEAD_REGISTER,
(UCHAR)(devExt->DeviceUnit | (devExt->TracksPerCylinder - 1)));
WRITE_PORT_UCHAR(ControllerData->ControllerAddress + COMMAND_REGISTER,
RECALIBRATE_COMMAND);
//
// wait for things to settle down
//
IdeWaitControllerReady(ControllerData, 20, 150000);
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -