📄 utils.c
字号:
/*++
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 + -