📄 geometry.c
字号:
/*++
Copyright (C) Microsoft Corporation, 1991 - 1999
Module Name:
geometry.c
Abstract:
SCSI disk class driver - this module contains all the code for generating
disk geometries.
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include "disk.h"
#include "ntddstor.h"
#if defined(_X86_) || defined(_AMD64_)
DISK_GEOMETRY_SOURCE
DiskUpdateGeometry(
IN PFUNCTIONAL_DEVICE_EXTENSION DeviceExtension
);
NTSTATUS
DiskUpdateRemovableGeometry (
IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
);
VOID
DiskScanBusDetectInfo(
IN PDRIVER_OBJECT DriverObject,
IN HANDLE BusKey
);
NTSTATUS
DiskSaveBusDetectInfo(
IN PDRIVER_OBJECT DriverObject,
IN HANDLE TargetKey,
IN ULONG DiskNumber
);
NTSTATUS
DiskSaveGeometryDetectInfo(
IN PDRIVER_OBJECT DriverObject,
IN HANDLE HardwareKey
);
NTSTATUS
DiskGetPortGeometry(
IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
OUT PDISK_GEOMETRY Geometry
);
typedef struct _DISK_DETECT_INFO {
BOOLEAN Initialized;
ULONG Style;
ULONG Signature;
ULONG MbrCheckSum;
PDEVICE_OBJECT Device;
CM_INT13_DRIVE_PARAMETER DriveParameters;
} DISK_DETECT_INFO, *PDISK_DETECT_INFO;
//
// Information about the disk geometries collected and saved into the registry
// by NTDETECT.COM or the system firmware.
//
PDISK_DETECT_INFO DetectInfoList = NULL;
ULONG DetectInfoCount = 0;
ULONG DetectInfoUsedCount = 0;
#define GET_STARTING_SECTOR(p) ( \
(ULONG) (p->StartingSectorLsb0) + \
(ULONG) (p->StartingSectorLsb1 << 8 ) + \
(ULONG) (p->StartingSectorMsb0 << 16) + \
(ULONG) (p->StartingSectorMsb1 << 24) )
#define GET_ENDING_S_OF_CHS(p) ( \
(UCHAR) (p->EndingCylinderLsb & 0x3F) )
//
// Definitions from hal.h
//
//
// Boot record disk partition table entry structure format
//
typedef struct _PARTITION_DESCRIPTOR
{
UCHAR ActiveFlag;
UCHAR StartingTrack;
UCHAR StartingCylinderLsb;
UCHAR StartingCylinderMsb;
UCHAR PartitionType;
UCHAR EndingTrack;
UCHAR EndingCylinderLsb;
UCHAR EndingCylinderMsb;
UCHAR StartingSectorLsb0;
UCHAR StartingSectorLsb1;
UCHAR StartingSectorMsb0;
UCHAR StartingSectorMsb1;
UCHAR PartitionLengthLsb0;
UCHAR PartitionLengthLsb1;
UCHAR PartitionLengthMsb0;
UCHAR PartitionLengthMsb1;
} PARTITION_DESCRIPTOR, *PPARTITION_DESCRIPTOR;
//
// Number of partition table entries
//
#define NUM_PARTITION_TABLE_ENTRIES 4
//
// Partition table record and boot signature offsets in 16-bit words
//
#define PARTITION_TABLE_OFFSET ( 0x1be / 2)
#define BOOT_SIGNATURE_OFFSET ((0x200 / 2) - 1)
//
// Boot record signature value
//
#define BOOT_RECORD_SIGNATURE (0xaa55)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DiskSaveDetectInfo)
#pragma alloc_text(INIT, DiskScanBusDetectInfo)
#pragma alloc_text(INIT, DiskSaveBusDetectInfo)
#pragma alloc_text(INIT, DiskSaveGeometryDetectInfo)
#pragma alloc_text(PAGE, DiskUpdateGeometry)
#pragma alloc_text(PAGE, DiskUpdateRemovableGeometry)
#pragma alloc_text(PAGE, DiskGetPortGeometry)
#pragma alloc_text(PAGE, DiskIsNT4Geometry)
#pragma alloc_text(PAGE, DiskGetDetectInfo)
#pragma alloc_text(PAGE, DiskReadSignature)
#endif
NTSTATUS
DiskSaveDetectInfo(
PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine saves away the firmware information about the disks which has
been saved in the registry. It generates a list (DetectInfoList) which
contains the disk geometries, signatures & checksums of all drives which
were examined by NtDetect. This list is later used to assign geometries
to disks as they are initialized.
Arguments:
DriverObject - the driver being initialized. This is used to get to the
hardware database.
Return Value:
status.
--*/
{
OBJECT_ATTRIBUTES objectAttributes = {0};
HANDLE hardwareKey;
UNICODE_STRING unicodeString;
HANDLE busKey;
NTSTATUS status;
PAGED_CODE();
InitializeObjectAttributes(
&objectAttributes,
DriverObject->HardwareDatabase,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
//
// Create the hardware base key.
//
status = ZwOpenKey(&hardwareKey, KEY_READ, &objectAttributes);
if(!NT_SUCCESS(status)) {
DebugPrint((1, "DiskSaveDetectInfo: Cannot open hardware data. "
"Name: %wZ\n",
DriverObject->HardwareDatabase));
return status;
}
status = DiskSaveGeometryDetectInfo(DriverObject, hardwareKey);
if(!NT_SUCCESS(status)) {
DebugPrint((1, "DiskSaveDetectInfo: Can't query configuration data "
"(%#08lx)\n",
status));
ZwClose(hardwareKey);
return status;
}
//
// Open EISA bus key.
//
RtlInitUnicodeString(&unicodeString, L"EisaAdapter");
InitializeObjectAttributes(&objectAttributes,
&unicodeString,
OBJ_CASE_INSENSITIVE,
hardwareKey,
NULL);
status = ZwOpenKey(&busKey,
KEY_READ,
&objectAttributes);
if(NT_SUCCESS(status)) {
DebugPrint((1, "DiskSaveDetectInfo: Opened EisaAdapter key\n"));
DiskScanBusDetectInfo(DriverObject, busKey);
ZwClose(busKey);
}
//
// Open MultiFunction bus key.
//
RtlInitUnicodeString(&unicodeString, L"MultifunctionAdapter");
InitializeObjectAttributes(&objectAttributes,
&unicodeString,
OBJ_CASE_INSENSITIVE,
hardwareKey,
NULL);
status = ZwOpenKey(&busKey,
KEY_READ,
&objectAttributes);
if(NT_SUCCESS(status)) {
DebugPrint((1, "DiskSaveDetectInfo: Opened MultifunctionAdapter key\n"));
DiskScanBusDetectInfo(DriverObject, busKey);
ZwClose(busKey);
}
ZwClose(hardwareKey);
return STATUS_SUCCESS;
}
VOID
DiskCleanupDetectInfo(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine will cleanup the data structure built by DiskSaveDetectInfo.
Arguments:
DriverObject - a pointer to the kernel object for this driver.
Return Value:
none
--*/
{
if (DetectInfoList != NULL) {
ExFreePool(DetectInfoList);
DetectInfoList = NULL;
}
return;
}
NTSTATUS
DiskSaveGeometryDetectInfo(
IN PDRIVER_OBJECT DriverObject,
IN HANDLE HardwareKey
)
{
UNICODE_STRING unicodeString;
PKEY_VALUE_FULL_INFORMATION keyData;
ULONG length;
PCM_FULL_RESOURCE_DESCRIPTOR fullDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
PCM_INT13_DRIVE_PARAMETER driveParameters;
ULONG numberOfDrives;
ULONG i;
NTSTATUS status;
PAGED_CODE();
//
// Get disk BIOS geometry information.
//
RtlInitUnicodeString(&unicodeString, L"Configuration Data");
keyData = ExAllocatePoolWithTag(PagedPool,
VALUE_BUFFER_SIZE,
DISK_TAG_UPDATE_GEOM);
if(keyData == NULL) {
DebugPrint((1, "DiskSaveGeometryDetectInfo: Can't allocate config "
"data buffer\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
status = ZwQueryValueKey(HardwareKey,
&unicodeString,
KeyValueFullInformation,
keyData,
VALUE_BUFFER_SIZE,
&length);
if(!NT_SUCCESS(status)) {
DebugPrint((1, "DiskSaveGeometryDetectInfo: Can't query configuration "
"data (%#08lx)\n",
status));
ExFreePool(keyData);
return status;
}
//
// Extract the resource list out of the key data.
//
fullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
(((PUCHAR) keyData) + keyData->DataOffset);
partialDescriptor =
fullDescriptor->PartialResourceList.PartialDescriptors;
length = partialDescriptor->u.DeviceSpecificData.DataSize;
if((keyData->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) ||
(fullDescriptor->PartialResourceList.Count == 0) ||
(partialDescriptor->Type != CmResourceTypeDeviceSpecific) ||
(length < sizeof(ULONG))) {
DebugPrint((1, "DiskSaveGeometryDetectInfo: BIOS header data too small "
"or invalid\n"));
ExFreePool(keyData);
return STATUS_INVALID_PARAMETER;
}
//
// Point to the BIOS data. THe BIOS data is located after the first
// partial Resource list which should be device specific data.
//
{
PUCHAR buffer = (PUCHAR) keyData;
buffer += keyData->DataOffset;
buffer += sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
driveParameters = (PCM_INT13_DRIVE_PARAMETER) buffer;
}
numberOfDrives = length / sizeof(CM_INT13_DRIVE_PARAMETER);
//
// Allocate our detect info list now that we know how many entries there
// are going to be. No other routine allocates detect info and this is
// done out of DriverEntry so we don't need to synchronize it's creation.
//
length = sizeof(DISK_DETECT_INFO) * numberOfDrives;
DetectInfoList = ExAllocatePoolWithTag(PagedPool,
length,
DISK_TAG_UPDATE_GEOM);
if(DetectInfoList == NULL) {
DebugPrint((1, "DiskSaveGeometryDetectInfo: Couldn't allocate %x bytes "
"for DetectInfoList\n",
length));
ExFreePool(keyData);
return STATUS_INSUFFICIENT_RESOURCES;
}
DetectInfoCount = numberOfDrives;
RtlZeroMemory(DetectInfoList, length);
//
// Copy the information out of the key data and into the list we've
// allocated.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -