2 * PROJECT: ReactOS Storage Stack / SCSIPORT storage port library
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Registry operations
5 * COPYRIGHT: Eric Kohl (eric.kohl@reactos.org)
6 * Aleksey Bragin (aleksey@reactos.org)
17 _Inout_ PCONFIGURATION_INFO ConfigInfo
,
18 _In_ PUNICODE_STRING RegistryPath
)
20 OBJECT_ATTRIBUTES ObjectAttributes
;
21 UNICODE_STRING KeyName
;
24 /* Open the service key */
25 InitializeObjectAttributes(&ObjectAttributes
,
31 Status
= ZwOpenKey(&ConfigInfo
->ServiceKey
,
35 if (!NT_SUCCESS(Status
))
37 DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath
, Status
);
38 ConfigInfo
->ServiceKey
= NULL
;
41 /* If we could open driver's service key, then proceed to the Parameters key */
42 if (ConfigInfo
->ServiceKey
!= NULL
)
44 RtlInitUnicodeString(&KeyName
, L
"Parameters");
45 InitializeObjectAttributes(&ObjectAttributes
,
48 ConfigInfo
->ServiceKey
,
49 (PSECURITY_DESCRIPTOR
) NULL
);
52 Status
= ZwOpenKey(&ConfigInfo
->DeviceKey
,
56 if (NT_SUCCESS(Status
))
58 /* Yes, Parameters key exist, and it must be used instead of
60 ZwClose(ConfigInfo
->ServiceKey
);
61 ConfigInfo
->ServiceKey
= ConfigInfo
->DeviceKey
;
62 ConfigInfo
->DeviceKey
= NULL
;
66 if (ConfigInfo
->ServiceKey
!= NULL
)
68 /* Open the Device key */
69 RtlInitUnicodeString(&KeyName
, L
"Device");
70 InitializeObjectAttributes(&ObjectAttributes
,
73 ConfigInfo
->ServiceKey
,
76 /* We don't check for failure here - not needed */
77 ZwOpenKey(&ConfigInfo
->DeviceKey
,
83 /**********************************************************************
88 * Builds the registry device map of all device which are attached
89 * to the given SCSI HBA port. The device map is located at:
90 * \Registry\Machine\DeviceMap\Scsi
100 * Name of registry driver service key.
108 _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
,
109 _In_ PUNICODE_STRING RegistryPath
)
111 PSCSI_PORT_LUN_EXTENSION LunExtension
;
112 OBJECT_ATTRIBUTES ObjectAttributes
;
113 UNICODE_STRING KeyName
;
114 UNICODE_STRING ValueName
;
115 WCHAR NameBuffer
[64];
118 HANDLE ScsiPortKey
= NULL
;
119 HANDLE ScsiBusKey
= NULL
;
120 HANDLE ScsiInitiatorKey
= NULL
;
121 HANDLE ScsiTargetKey
= NULL
;
122 HANDLE ScsiLunKey
= NULL
;
132 DPRINT("SpiBuildDeviceMap() called\n");
134 if (DeviceExtension
== NULL
|| RegistryPath
== NULL
)
136 DPRINT1("Invalid parameter\n");
137 return STATUS_INVALID_PARAMETER
;
140 /* Open or create the 'Scsi' subkey */
141 RtlInitUnicodeString(&KeyName
,
142 L
"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
143 InitializeObjectAttributes(&ObjectAttributes
,
145 OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
| OBJ_KERNEL_HANDLE
,
148 Status
= ZwCreateKey(&ScsiKey
,
155 if (!NT_SUCCESS(Status
))
157 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
161 /* Create new 'Scsi Port X' subkey */
162 DPRINT("Scsi Port %lu\n", DeviceExtension
->PortNumber
);
166 DeviceExtension
->PortNumber
);
167 RtlInitUnicodeString(&KeyName
, NameBuffer
);
168 InitializeObjectAttributes(&ObjectAttributes
,
173 Status
= ZwCreateKey(&ScsiPortKey
,
181 if (!NT_SUCCESS(Status
))
183 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
188 * Create port-specific values
191 /* Set 'DMA Enabled' (REG_DWORD) value */
192 UlongData
= (ULONG
)!DeviceExtension
->PortCapabilities
.AdapterUsesPio
;
193 DPRINT(" DMA Enabled = %s\n", UlongData
? "TRUE" : "FALSE");
194 RtlInitUnicodeString(&ValueName
, L
"DMA Enabled");
195 Status
= ZwSetValueKey(ScsiPortKey
,
201 if (!NT_SUCCESS(Status
))
203 DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status
);
204 ZwClose(ScsiPortKey
);
208 /* Set 'Driver' (REG_SZ) value */
209 DriverName
= wcsrchr(RegistryPath
->Buffer
, L
'\\') + 1;
210 RtlInitUnicodeString(&ValueName
, L
"Driver");
211 Status
= ZwSetValueKey(ScsiPortKey
,
216 (ULONG
)((wcslen(DriverName
) + 1) * sizeof(WCHAR
)));
217 if (!NT_SUCCESS(Status
))
219 DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status
);
220 ZwClose(ScsiPortKey
);
224 /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
225 UlongData
= (ULONG
)DeviceExtension
->PortConfig
->BusInterruptLevel
;
226 DPRINT(" Interrupt = %lu\n", UlongData
);
227 RtlInitUnicodeString(&ValueName
, L
"Interrupt");
228 Status
= ZwSetValueKey(ScsiPortKey
,
234 if (!NT_SUCCESS(Status
))
236 DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status
);
237 ZwClose(ScsiPortKey
);
241 /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
242 UlongData
= ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension
->PortConfig
->AccessRanges
)[0].RangeStart
);
243 DPRINT(" IOAddress = %lx\n", UlongData
);
244 RtlInitUnicodeString(&ValueName
, L
"IOAddress");
245 Status
= ZwSetValueKey(ScsiPortKey
,
251 if (!NT_SUCCESS(Status
))
253 DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status
);
254 ZwClose(ScsiPortKey
);
258 /* Enumerate buses */
259 for (BusNumber
= 0; BusNumber
< DeviceExtension
->PortConfig
->NumberOfBuses
; BusNumber
++)
261 /* Create 'Scsi Bus X' key */
262 DPRINT(" Scsi Bus %lu\n", BusNumber
);
266 RtlInitUnicodeString(&KeyName
, NameBuffer
);
267 InitializeObjectAttributes(&ObjectAttributes
,
272 Status
= ZwCreateKey(&ScsiBusKey
,
279 if (!NT_SUCCESS(Status
))
281 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
285 /* Create 'Initiator Id X' key */
286 DPRINT(" Initiator Id %lu\n",
287 DeviceExtension
->PortConfig
->InitiatorBusId
[BusNumber
]);
290 (ULONG
)(UCHAR
)DeviceExtension
->PortConfig
->InitiatorBusId
[BusNumber
]);
291 RtlInitUnicodeString(&KeyName
, NameBuffer
);
292 InitializeObjectAttributes(&ObjectAttributes
,
297 Status
= ZwCreateKey(&ScsiInitiatorKey
,
304 if (!NT_SUCCESS(Status
))
306 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
310 /* FIXME: Are there any initiator values (??) */
312 ZwClose(ScsiInitiatorKey
);
313 ScsiInitiatorKey
= NULL
;
316 /* Enumerate targets */
317 CurrentTarget
= (ULONG
)-1;
318 ScsiTargetKey
= NULL
;
319 for (Target
= 0; Target
< DeviceExtension
->PortConfig
->MaximumNumberOfTargets
; Target
++)
321 for (Lun
= 0; Lun
< SCSI_MAXIMUM_LOGICAL_UNITS
; Lun
++)
323 LunExtension
= SpiGetLunExtension(DeviceExtension
,
327 if (LunExtension
== NULL
)
330 if (Target
!= CurrentTarget
)
332 /* Close old target key */
333 if (ScsiTargetKey
!= NULL
)
335 ZwClose(ScsiTargetKey
);
336 ScsiTargetKey
= NULL
;
339 /* Create 'Target Id X' key */
340 DPRINT(" Target Id %lu\n", Target
);
344 RtlInitUnicodeString(&KeyName
, NameBuffer
);
345 InitializeObjectAttributes(&ObjectAttributes
,
350 Status
= ZwCreateKey(&ScsiTargetKey
,
357 if (!NT_SUCCESS(Status
))
359 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
363 CurrentTarget
= Target
;
366 /* Create 'Logical Unit Id X' key */
367 DPRINT(" Logical Unit Id %lu\n", Lun
);
369 L
"Logical Unit Id %lu",
371 RtlInitUnicodeString(&KeyName
, NameBuffer
);
372 InitializeObjectAttributes(&ObjectAttributes
,
377 Status
= ZwCreateKey(&ScsiLunKey
,
384 if (!NT_SUCCESS(Status
))
386 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status
);
390 /* Set 'Identifier' (REG_SZ) value */
393 LunExtension
->InquiryData
.VendorId
,
394 LunExtension
->InquiryData
.ProductId
,
395 LunExtension
->InquiryData
.ProductRevisionLevel
);
396 DPRINT(" Identifier = '%S'\n", NameBuffer
);
397 RtlInitUnicodeString(&ValueName
, L
"Identifier");
398 Status
= ZwSetValueKey(ScsiLunKey
,
403 (ULONG
)((wcslen(NameBuffer
) + 1) * sizeof(WCHAR
)));
404 if (!NT_SUCCESS(Status
))
406 DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status
);
410 /* Set 'Type' (REG_SZ) value */
412 * See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices
413 * and https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices
414 * for a list of types with their human-readable forms.
416 switch (LunExtension
->InquiryData
.DeviceType
)
419 TypeName
= L
"DiskPeripheral";
422 TypeName
= L
"TapePeripheral";
425 TypeName
= L
"PrinterPeripheral";
427 // case 3: "ProcessorPeripheral", classified as 'other': fall back to default case.
429 TypeName
= L
"WormPeripheral";
432 TypeName
= L
"CdRomPeripheral";
435 TypeName
= L
"ScannerPeripheral";
438 TypeName
= L
"OpticalDiskPeripheral";
441 TypeName
= L
"MediumChangerPeripheral";
444 TypeName
= L
"CommunicationsPeripheral";
447 /* New peripheral types (SCSI only) */
449 TypeName
= L
"ASCPrePressGraphicsPeripheral";
452 TypeName
= L
"ArrayPeripheral";
455 TypeName
= L
"EnclosurePeripheral";
458 TypeName
= L
"RBCPeripheral";
461 TypeName
= L
"CardReaderPeripheral";
464 TypeName
= L
"BridgePeripheral";
468 TypeName
= L
"OtherPeripheral";
471 DPRINT(" Type = '%S'\n", TypeName
);
472 RtlInitUnicodeString(&ValueName
, L
"Type");
473 Status
= ZwSetValueKey(ScsiLunKey
,
478 (ULONG
)((wcslen(TypeName
) + 1) * sizeof(WCHAR
)));
479 if (!NT_SUCCESS(Status
))
481 DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status
);
489 /* Close old target key */
490 if (ScsiTargetKey
!= NULL
)
492 ZwClose(ScsiTargetKey
);
493 ScsiTargetKey
= NULL
;
502 if (ScsiLunKey
!= NULL
)
505 if (ScsiInitiatorKey
!= NULL
)
506 ZwClose(ScsiInitiatorKey
);
508 if (ScsiTargetKey
!= NULL
)
509 ZwClose(ScsiTargetKey
);
511 if (ScsiBusKey
!= NULL
)
514 if (ScsiPortKey
!= NULL
)
515 ZwClose(ScsiPortKey
);
517 DPRINT("SpiBuildDeviceMap() done\n");