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

📄 utils.c

📁 This is the library for all storage drivers. It simplifies writing a storage driver by implementing
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    utils.c

Abstract:

    SCSI class driver routines

Environment:

    kernel mode only

Notes:


Revision History:

--*/

#include "classp.h"
#include "debug.h"



#ifdef ALLOC_PRAGMA
    #pragma alloc_text(PAGE, ClassGetDeviceParameter)
    #pragma alloc_text(PAGE, ClassScanForSpecial)
    #pragma alloc_text(PAGE, ClassSetDeviceParameter)
#endif



// custom string match -- careful!
BOOLEAN ClasspMyStringMatches(IN PCHAR StringToMatch OPTIONAL, IN PCHAR TargetString)
{
    ULONG length;  // strlen returns an int, not size_t (!)
    PAGED_CODE();
    ASSERT(TargetString);
    // if no match requested, return TRUE
    if (StringToMatch == NULL) {
        return TRUE;
    }
    // cache the string length for efficiency
    length = strlen(StringToMatch);
    // ZERO-length strings may only match zero-length strings
    if (length == 0) {
        return (strlen(TargetString) == 0);
    }
    // strncmp returns zero if the strings match
    return (strncmp(StringToMatch, TargetString, length) == 0);
}


VOID ClassGetDeviceParameter(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN PWSTR SubkeyName OPTIONAL,
    IN PWSTR ParameterName,
    IN OUT PULONG ParameterValue  // also default value
    )
{
    NTSTATUS                 status;
    RTL_QUERY_REGISTRY_TABLE queryTable[2] = {0};
    HANDLE                   deviceParameterHandle;
    HANDLE                   deviceSubkeyHandle;
    ULONG                    defaultParameterValue;

    PAGED_CODE();

    //
    // open the given parameter
    //

    status = IoOpenDeviceRegistryKey(FdoExtension->LowerPdo,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     KEY_READ,
                                     &deviceParameterHandle);

    if (NT_SUCCESS(status) && (SubkeyName != NULL)) {

        UNICODE_STRING subkeyName;
        OBJECT_ATTRIBUTES objectAttributes = {0};

        RtlInitUnicodeString(&subkeyName, SubkeyName);
        InitializeObjectAttributes(&objectAttributes,
                                   &subkeyName,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   deviceParameterHandle,
                                   NULL);

        status = ZwOpenKey(&deviceSubkeyHandle,
                           KEY_READ,
                           &objectAttributes);
        if (!NT_SUCCESS(status)) {
            ZwClose(deviceParameterHandle);
        }

    }

    if (NT_SUCCESS(status)) {

        defaultParameterValue = *ParameterValue;

        queryTable->Flags         = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
        queryTable->Name          = ParameterName;
        queryTable->EntryContext  = ParameterValue;
        queryTable->DefaultType   = REG_DWORD;
        queryTable->DefaultData   = NULL;
        queryTable->DefaultLength = 0;

        status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
                                        (PWSTR)(SubkeyName ?
                                                deviceSubkeyHandle :
                                                deviceParameterHandle),
                                        queryTable,
                                        NULL,
                                        NULL);
        if (!NT_SUCCESS(status)) {
            *ParameterValue = defaultParameterValue; // use default value
        }

        //
        // close what we open
        //

        if (SubkeyName) {
            ZwClose(deviceSubkeyHandle);
        }

        ZwClose(deviceParameterHandle);
    }

    if (!NT_SUCCESS(status)) {

        //
        // Windows 2000 SP3 uses the driver-specific key, so look in there
        //

        status = IoOpenDeviceRegistryKey(FdoExtension->LowerPdo,
                                         PLUGPLAY_REGKEY_DRIVER,
                                         KEY_READ,
                                         &deviceParameterHandle);

        if (NT_SUCCESS(status) && (SubkeyName != NULL)) {

            UNICODE_STRING subkeyName;
            OBJECT_ATTRIBUTES objectAttributes = {0};

            RtlInitUnicodeString(&subkeyName, SubkeyName);
            InitializeObjectAttributes(&objectAttributes,
                                       &subkeyName,
                                       OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                       deviceParameterHandle,
                                       NULL);

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

            if (!NT_SUCCESS(status)) {
                ZwClose(deviceParameterHandle);
            }
        }

        if (NT_SUCCESS(status)) {

            defaultParameterValue = *ParameterValue;

            queryTable->Flags         = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
            queryTable->Name          = ParameterName;
            queryTable->EntryContext  = ParameterValue;
            queryTable->DefaultType   = REG_DWORD;
            queryTable->DefaultData   = NULL;
            queryTable->DefaultLength = 0;

            status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
                                            (PWSTR)(SubkeyName ?
                                                    deviceSubkeyHandle :
                                                    deviceParameterHandle),
                                            queryTable,
                                            NULL,
                                            NULL);
            if (NT_SUCCESS(status)) {

                //
                // Migrate the value over to the device-specific key
                //

                ClassSetDeviceParameter(FdoExtension, SubkeyName, ParameterName, *ParameterValue);

            } else {

                //
                // Use the default value
                //

                *ParameterValue = defaultParameterValue;
            }

            if (SubkeyName) {
                ZwClose(deviceSubkeyHandle);
            }

            ZwClose(deviceParameterHandle);
        }
    }

    return;

} // end ClassGetDeviceParameter()


NTSTATUS ClassSetDeviceParameter(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN PWSTR SubkeyName OPTIONAL,
    IN PWSTR ParameterName,
    IN ULONG ParameterValue)
{
    NTSTATUS                 status;
    HANDLE                   deviceParameterHandle;
    HANDLE                   deviceSubkeyHandle;

    PAGED_CODE();

    //
    // open the given parameter
    //

    status = IoOpenDeviceRegistryKey(FdoExtension->LowerPdo,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     KEY_READ | KEY_WRITE,
                                     &deviceParameterHandle);

    if (NT_SUCCESS(status) && (SubkeyName != NULL)) {

        UNICODE_STRING subkeyName;
        OBJECT_ATTRIBUTES objectAttributes;

        RtlInitUnicodeString(&subkeyName, SubkeyName);
        InitializeObjectAttributes(&objectAttributes,
                                   &subkeyName,
                                   OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                                   deviceParameterHandle,
                                   NULL);

        status = ZwCreateKey(&deviceSubkeyHandle,
                             KEY_READ | KEY_WRITE,
                             &objectAttributes,
                             0, NULL, 0, NULL);
        if (!NT_SUCCESS(status)) {
            ZwClose(deviceParameterHandle);
        }

    }

    if (NT_SUCCESS(status)) {

        status = RtlWriteRegistryValue(
            RTL_REGISTRY_HANDLE,
            (PWSTR) (SubkeyName ?
                     deviceSubkeyHandle :
                     deviceParameterHandle),
            ParameterName,
            REG_DWORD,
            &ParameterValue,
            sizeof(ULONG));

        //
        // close what we open
        //

        if (SubkeyName) {
            ZwClose(deviceSubkeyHandle);
        }

        ZwClose(deviceParameterHandle);
    }

    return status;

} // end ClassSetDeviceParameter()


/*
 *  ClassScanForSpecial
 *
 *      This routine was written to simplify scanning for special
 *      hardware based upon id strings.  it does not check the registry.
 */

VOID ClassScanForSpecial(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN CLASSPNP_SCAN_FOR_SPECIAL_INFO DeviceList[],
    IN PCLASS_SCAN_FOR_SPECIAL_HANDLER Function)
{
    PSTORAGE_DEVICE_DESCRIPTOR deviceDescriptor;
    PUCHAR vendorId;
    PUCHAR productId;
    PUCHAR productRevision;
    UCHAR nullString[] = "";
    ULONG j;

    PAGED_CODE();
    ASSERT(DeviceList);
    ASSERT(Function);

    deviceDescriptor = FdoExtension->DeviceDescriptor;

    if (DeviceList == NULL) {
        return;
    }
    if (Function == NULL) {
        return;
    }

    //
    // SCSI sets offsets to -1, ATAPI sets to 0.  check for both.
    //

⌨️ 快捷键说明

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