⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geometry.c

📁 The Disk sample is used with Classpnp.sys as disk driver. The sample supports Plug and Play, Power M
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

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_)

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;

#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, 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;
    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.
    //

    for(i = 0; i < numberOfDrives; i++) {
        DetectInfoList[i].DriveParameters = driveParameters[i];
    }

    ExFreePool(keyData);
    return STATUS_SUCCESS;
}


VOID
DiskScanBusDetectInfo(
    IN PDRIVER_OBJECT DriverObject,
    IN HANDLE BusKey
    )
/*++

Routine Description:

    The routine queries the registry to determine which disks are visible to
    the BIOS.  If a disk is visable to the BIOS then the geometry information
    is updated with the disk's signature and MBR checksum.

Arguments:

    DriverObject - the object for this driver.
    BusKey - handle to the bus key to be enumerated.

Return Value:

    status
    
--*/
{
    ULONG busNumber;

    NTSTATUS status;

    for(busNumber = 0; ; busNumber++) {

        WCHAR buffer[32];
        UNICODE_STRING unicodeString;

        OBJECT_ATTRIBUTES objectAttributes;

        HANDLE spareKey;
        HANDLE adapterKey;

        ULONG adapterNumber;

        DebugPrint((1, "DiskScanBusDetectInfo: Scanning bus %d\n", busNumber));

        //
        // Open controller name key.
        //

        swprintf(buffer, L"%d", busNumber);
        RtlInitUnicodeString(&unicodeString, buffer);

        InitializeObjectAttributes(&objectAttributes,
                                   &unicodeString,
                                   OBJ_CASE_INSENSITIVE,
                                   BusKey,
                                   NULL);

        status = ZwOpenKey(&spareKey, KEY_READ, &objectAttributes);

        if(!NT_SUCCESS(status)) {
            DebugPrint((1, "DiskScanBusDetectInfo: Error %#08lx opening bus "
                           "key %#x\n", 
                        status, busNumber));
            break;
        }

        //
        // Open up a controller ordinal key.
        //

        RtlInitUnicodeString(&unicodeString, L"DiskController");
        InitializeObjectAttributes(&objectAttributes,
                                   &unicodeString,
                                   OBJ_CASE_INSENSITIVE,
                                   spareKey,
                                   NULL);

        status = ZwOpenKey(&adapterKey, KEY_READ, &objectAttributes);
        ZwClose(spareKey);

        if(!NT_SUCCESS(status)) {
            DebugPrint((1, "DiskScanBusDetectInfo: Error %#08lx opening "
                           "DiskController key\n", 
                           status));
            continue;
        }

        for(adapterNumber = 0; ; adapterNumber++) {

            HANDLE diskKey;
            ULONG diskNumber;
            
            //
            // Open disk key.
            //

            DebugPrint((1, "DiskScanBusDetectInfo: Scanning disk key "
                           "%d\\DiskController\\%d\\DiskPeripheral\n",
                           busNumber, adapterNumber));

            swprintf(buffer, L"%d\\DiskPeripheral", adapterNumber);
            RtlInitUnicodeString(&unicodeString, buffer);

            InitializeObjectAttributes(&objectAttributes,
                                       &unicodeString,
                                       OBJ_CASE_INSENSITIVE,
                                       adapterKey,
                                       NULL);

            status = ZwOpenKey(&diskKey, KEY_READ, &objectAttributes);

            if(!NT_SUCCESS(status)) {
                DebugPrint((1, "DiskScanBusDetectInfo: Error %#08lx opening "
                               "disk key\n",
                               status));
                break;
            }

            for(diskNumber = 0; ; diskNumber++) {

                HANDLE targetKey;

                DebugPrint((1, "DiskScanBusDetectInfo: Scanning target key "
                               "%d\\DiskController\\%d\\DiskPeripheral\\%d\n",
                               busNumber, adapterNumber, diskNumber));

                swprintf(buffer, L"%d", diskNumber);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -