mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 07:26:20 +00:00
[SCSIPORT] Split scsiport.c file into several ones, prepare for the refactoring
CORE-17132
This commit is contained in:
parent
9be9750dc8
commit
1b45d9ee4b
8 changed files with 3462 additions and 3381 deletions
520
drivers/storage/port/scsiport/registry.c
Normal file
520
drivers/storage/port/scsiport/registry.c
Normal file
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Storage Stack / SCSIPORT storage port library
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Registry operations
|
||||
* COPYRIGHT: Eric Kohl (eric.kohl@reactos.org)
|
||||
* Aleksey Bragin (aleksey@reactos.org)
|
||||
*/
|
||||
|
||||
#include "scsiport.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
VOID
|
||||
SpiInitOpenKeys(
|
||||
_Inout_ PCONFIGURATION_INFO ConfigInfo,
|
||||
_In_ PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Open the service key */
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
RegistryPath,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ZwOpenKey(&ConfigInfo->ServiceKey,
|
||||
KEY_READ,
|
||||
&ObjectAttributes);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath, Status);
|
||||
ConfigInfo->ServiceKey = NULL;
|
||||
}
|
||||
|
||||
/* If we could open driver's service key, then proceed to the Parameters key */
|
||||
if (ConfigInfo->ServiceKey != NULL)
|
||||
{
|
||||
RtlInitUnicodeString(&KeyName, L"Parameters");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ConfigInfo->ServiceKey,
|
||||
(PSECURITY_DESCRIPTOR) NULL);
|
||||
|
||||
/* Try to open it */
|
||||
Status = ZwOpenKey(&ConfigInfo->DeviceKey,
|
||||
KEY_READ,
|
||||
&ObjectAttributes);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Yes, Parameters key exist, and it must be used instead of
|
||||
the Service key */
|
||||
ZwClose(ConfigInfo->ServiceKey);
|
||||
ConfigInfo->ServiceKey = ConfigInfo->DeviceKey;
|
||||
ConfigInfo->DeviceKey = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ConfigInfo->ServiceKey != NULL)
|
||||
{
|
||||
/* Open the Device key */
|
||||
RtlInitUnicodeString(&KeyName, L"Device");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
ConfigInfo->ServiceKey,
|
||||
NULL);
|
||||
|
||||
/* We don't check for failure here - not needed */
|
||||
ZwOpenKey(&ConfigInfo->DeviceKey,
|
||||
KEY_READ,
|
||||
&ObjectAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME INTERNAL
|
||||
* SpiBuildDeviceMap
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Builds the registry device map of all device which are attached
|
||||
* to the given SCSI HBA port. The device map is located at:
|
||||
* \Registry\Machine\DeviceMap\Scsi
|
||||
*
|
||||
* RUN LEVEL
|
||||
* PASSIVE_LEVEL
|
||||
*
|
||||
* ARGUMENTS
|
||||
* DeviceExtension
|
||||
* ...
|
||||
*
|
||||
* RegistryPath
|
||||
* Name of registry driver service key.
|
||||
*
|
||||
* RETURNS
|
||||
* NTSTATUS
|
||||
*/
|
||||
|
||||
NTSTATUS
|
||||
SpiBuildDeviceMap(
|
||||
_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
_In_ PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
UNICODE_STRING ValueName;
|
||||
WCHAR NameBuffer[64];
|
||||
ULONG Disposition;
|
||||
HANDLE ScsiKey;
|
||||
HANDLE ScsiPortKey = NULL;
|
||||
HANDLE ScsiBusKey = NULL;
|
||||
HANDLE ScsiInitiatorKey = NULL;
|
||||
HANDLE ScsiTargetKey = NULL;
|
||||
HANDLE ScsiLunKey = NULL;
|
||||
ULONG BusNumber;
|
||||
ULONG Target;
|
||||
ULONG CurrentTarget;
|
||||
ULONG Lun;
|
||||
PWCHAR DriverName;
|
||||
ULONG UlongData;
|
||||
PWCHAR TypeName;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("SpiBuildDeviceMap() called\n");
|
||||
|
||||
if (DeviceExtension == NULL || RegistryPath == NULL)
|
||||
{
|
||||
DPRINT1("Invalid parameter\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Open or create the 'Scsi' subkey */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_KERNEL_HANDLE,
|
||||
0,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Create new 'Scsi Port X' subkey */
|
||||
DPRINT("Scsi Port %lu\n", DeviceExtension->PortNumber);
|
||||
|
||||
swprintf(NameBuffer,
|
||||
L"Scsi Port %lu",
|
||||
DeviceExtension->PortNumber);
|
||||
RtlInitUnicodeString(&KeyName, NameBuffer);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_KERNEL_HANDLE,
|
||||
ScsiKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiPortKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
ZwClose(ScsiKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create port-specific values
|
||||
*/
|
||||
|
||||
/* Set 'DMA Enabled' (REG_DWORD) value */
|
||||
UlongData = (ULONG)!DeviceExtension->PortCapabilities.AdapterUsesPio;
|
||||
DPRINT(" DMA Enabled = %s\n", UlongData ? "TRUE" : "FALSE");
|
||||
RtlInitUnicodeString(&ValueName, L"DMA Enabled");
|
||||
Status = ZwSetValueKey(ScsiPortKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&UlongData,
|
||||
sizeof(UlongData));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
|
||||
ZwClose(ScsiPortKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set 'Driver' (REG_SZ) value */
|
||||
DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1;
|
||||
RtlInitUnicodeString(&ValueName, L"Driver");
|
||||
Status = ZwSetValueKey(ScsiPortKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
DriverName,
|
||||
(ULONG)((wcslen(DriverName) + 1) * sizeof(WCHAR)));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
|
||||
ZwClose(ScsiPortKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
|
||||
UlongData = (ULONG)DeviceExtension->PortConfig->BusInterruptLevel;
|
||||
DPRINT(" Interrupt = %lu\n", UlongData);
|
||||
RtlInitUnicodeString(&ValueName, L"Interrupt");
|
||||
Status = ZwSetValueKey(ScsiPortKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&UlongData,
|
||||
sizeof(UlongData));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
|
||||
ZwClose(ScsiPortKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
|
||||
UlongData = ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension->PortConfig->AccessRanges)[0].RangeStart);
|
||||
DPRINT(" IOAddress = %lx\n", UlongData);
|
||||
RtlInitUnicodeString(&ValueName, L"IOAddress");
|
||||
Status = ZwSetValueKey(ScsiPortKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&UlongData,
|
||||
sizeof(UlongData));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
|
||||
ZwClose(ScsiPortKey);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate buses */
|
||||
for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig->NumberOfBuses; BusNumber++)
|
||||
{
|
||||
/* Create 'Scsi Bus X' key */
|
||||
DPRINT(" Scsi Bus %lu\n", BusNumber);
|
||||
swprintf(NameBuffer,
|
||||
L"Scsi Bus %lu",
|
||||
BusNumber);
|
||||
RtlInitUnicodeString(&KeyName, NameBuffer);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
0,
|
||||
ScsiPortKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiBusKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Create 'Initiator Id X' key */
|
||||
DPRINT(" Initiator Id %lu\n",
|
||||
DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
|
||||
swprintf(NameBuffer,
|
||||
L"Initiator Id %lu",
|
||||
(ULONG)(UCHAR)DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
|
||||
RtlInitUnicodeString(&KeyName, NameBuffer);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
0,
|
||||
ScsiBusKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiInitiatorKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* FIXME: Are there any initiator values (??) */
|
||||
|
||||
ZwClose(ScsiInitiatorKey);
|
||||
ScsiInitiatorKey = NULL;
|
||||
|
||||
|
||||
/* Enumerate targets */
|
||||
CurrentTarget = (ULONG)-1;
|
||||
ScsiTargetKey = NULL;
|
||||
for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
|
||||
{
|
||||
for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
|
||||
{
|
||||
LunExtension = SpiGetLunExtension(DeviceExtension,
|
||||
(UCHAR)BusNumber,
|
||||
(UCHAR)Target,
|
||||
(UCHAR)Lun);
|
||||
if (LunExtension == NULL)
|
||||
continue;
|
||||
|
||||
if (Target != CurrentTarget)
|
||||
{
|
||||
/* Close old target key */
|
||||
if (ScsiTargetKey != NULL)
|
||||
{
|
||||
ZwClose(ScsiTargetKey);
|
||||
ScsiTargetKey = NULL;
|
||||
}
|
||||
|
||||
/* Create 'Target Id X' key */
|
||||
DPRINT(" Target Id %lu\n", Target);
|
||||
swprintf(NameBuffer,
|
||||
L"Target Id %lu",
|
||||
Target);
|
||||
RtlInitUnicodeString(&KeyName, NameBuffer);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
0,
|
||||
ScsiBusKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiTargetKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
CurrentTarget = Target;
|
||||
}
|
||||
|
||||
/* Create 'Logical Unit Id X' key */
|
||||
DPRINT(" Logical Unit Id %lu\n", Lun);
|
||||
swprintf(NameBuffer,
|
||||
L"Logical Unit Id %lu",
|
||||
Lun);
|
||||
RtlInitUnicodeString(&KeyName, NameBuffer);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
0,
|
||||
ScsiTargetKey,
|
||||
NULL);
|
||||
Status = ZwCreateKey(&ScsiLunKey,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
&Disposition);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Set 'Identifier' (REG_SZ) value */
|
||||
swprintf(NameBuffer,
|
||||
L"%.8S%.16S%.4S",
|
||||
LunExtension->InquiryData.VendorId,
|
||||
LunExtension->InquiryData.ProductId,
|
||||
LunExtension->InquiryData.ProductRevisionLevel);
|
||||
DPRINT(" Identifier = '%S'\n", NameBuffer);
|
||||
RtlInitUnicodeString(&ValueName, L"Identifier");
|
||||
Status = ZwSetValueKey(ScsiLunKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
NameBuffer,
|
||||
(ULONG)((wcslen(NameBuffer) + 1) * sizeof(WCHAR)));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
/* Set 'Type' (REG_SZ) value */
|
||||
/*
|
||||
* See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices
|
||||
* and https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices
|
||||
* for a list of types with their human-readable forms.
|
||||
*/
|
||||
switch (LunExtension->InquiryData.DeviceType)
|
||||
{
|
||||
case 0:
|
||||
TypeName = L"DiskPeripheral";
|
||||
break;
|
||||
case 1:
|
||||
TypeName = L"TapePeripheral";
|
||||
break;
|
||||
case 2:
|
||||
TypeName = L"PrinterPeripheral";
|
||||
break;
|
||||
// case 3: "ProcessorPeripheral", classified as 'other': fall back to default case.
|
||||
case 4:
|
||||
TypeName = L"WormPeripheral";
|
||||
break;
|
||||
case 5:
|
||||
TypeName = L"CdRomPeripheral";
|
||||
break;
|
||||
case 6:
|
||||
TypeName = L"ScannerPeripheral";
|
||||
break;
|
||||
case 7:
|
||||
TypeName = L"OpticalDiskPeripheral";
|
||||
break;
|
||||
case 8:
|
||||
TypeName = L"MediumChangerPeripheral";
|
||||
break;
|
||||
case 9:
|
||||
TypeName = L"CommunicationsPeripheral";
|
||||
break;
|
||||
|
||||
/* New peripheral types (SCSI only) */
|
||||
case 10: case 11:
|
||||
TypeName = L"ASCPrePressGraphicsPeripheral";
|
||||
break;
|
||||
case 12:
|
||||
TypeName = L"ArrayPeripheral";
|
||||
break;
|
||||
case 13:
|
||||
TypeName = L"EnclosurePeripheral";
|
||||
break;
|
||||
case 14:
|
||||
TypeName = L"RBCPeripheral";
|
||||
break;
|
||||
case 15:
|
||||
TypeName = L"CardReaderPeripheral";
|
||||
break;
|
||||
case 16:
|
||||
TypeName = L"BridgePeripheral";
|
||||
break;
|
||||
|
||||
default:
|
||||
TypeName = L"OtherPeripheral";
|
||||
break;
|
||||
}
|
||||
DPRINT(" Type = '%S'\n", TypeName);
|
||||
RtlInitUnicodeString(&ValueName, L"Type");
|
||||
Status = ZwSetValueKey(ScsiLunKey,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
TypeName,
|
||||
(ULONG)((wcslen(TypeName) + 1) * sizeof(WCHAR)));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
ZwClose(ScsiLunKey);
|
||||
ScsiLunKey = NULL;
|
||||
}
|
||||
|
||||
/* Close old target key */
|
||||
if (ScsiTargetKey != NULL)
|
||||
{
|
||||
ZwClose(ScsiTargetKey);
|
||||
ScsiTargetKey = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ZwClose(ScsiBusKey);
|
||||
ScsiBusKey = NULL;
|
||||
}
|
||||
|
||||
ByeBye:
|
||||
if (ScsiLunKey != NULL)
|
||||
ZwClose(ScsiLunKey);
|
||||
|
||||
if (ScsiInitiatorKey != NULL)
|
||||
ZwClose(ScsiInitiatorKey);
|
||||
|
||||
if (ScsiTargetKey != NULL)
|
||||
ZwClose(ScsiTargetKey);
|
||||
|
||||
if (ScsiBusKey != NULL)
|
||||
ZwClose(ScsiBusKey);
|
||||
|
||||
if (ScsiPortKey != NULL)
|
||||
ZwClose(ScsiPortKey);
|
||||
|
||||
DPRINT("SpiBuildDeviceMap() done\n");
|
||||
|
||||
return Status;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue