ReactOS 0.4.16-dev-329-g9223134
registry.c
Go to the documentation of this file.
1/*
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)
7 * 2020 Victor Perevertkin (victor.perevertkin@reactos.org)
8 */
9
10#include "scsiport.h"
11#include "scsitypes.h"
12
13#define NDEBUG
14#include <debug.h>
15
16
17VOID
21{
25 HANDLE parametersKey;
26
27 DriverExtension->IsLegacyDriver = TRUE;
28
29 /* Open the service key */
31 &DriverExtension->RegistryPath,
33 NULL,
34 NULL);
35
36 Status = ZwOpenKey(&ConfigInfo->ServiceKey, KEY_READ, &ObjectAttributes);
37
38 if (!NT_SUCCESS(Status))
39 {
40 DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n",
41 DriverExtension->RegistryPath, Status);
42 ConfigInfo->ServiceKey = NULL;
43 }
44
45 /* If we could open driver's service key, then proceed to the Parameters key */
46 if (ConfigInfo->ServiceKey != NULL)
47 {
48 RtlInitUnicodeString(&KeyName, L"Parameters");
50 &KeyName,
52 ConfigInfo->ServiceKey,
53 NULL);
54
55 /* Try to open it */
56 Status = ZwOpenKey(&ConfigInfo->DeviceKey, KEY_READ, &ObjectAttributes);
57
58 if (NT_SUCCESS(Status))
59 {
60 /* Yes, Parameters key exist, and it must be used instead of
61 the Service key */
62 ZwClose(ConfigInfo->ServiceKey);
63 ConfigInfo->ServiceKey = ConfigInfo->DeviceKey;
64 ConfigInfo->DeviceKey = NULL;
65 }
66 }
67
68 if (ConfigInfo->ServiceKey != NULL)
69 {
70 /* Open the Device key */
73 &KeyName,
75 ConfigInfo->ServiceKey,
76 NULL);
77
78 /* We don't check for failure here - not needed */
79 ZwOpenKey(&ConfigInfo->DeviceKey, KEY_READ, &ObjectAttributes);
80
81 // Detect the driver PnP capabilities via its Parameters\PnpInterface key
82 // for example: HKLM\SYSTEM\CurrentControlSet\Services\UNIATA\Parameters\PnpInterface
83
84 RtlInitUnicodeString(&KeyName, L"PnpInterface");
86 &KeyName,
88 ConfigInfo->ServiceKey,
89 NULL);
90
91 Status = ZwOpenKey(&parametersKey, KEY_READ, &ObjectAttributes);
92
93 if (NT_SUCCESS(Status))
94 {
95 // if the key exists, it's enough for us for now
96 // (the proper check should iterate over INTERFACE_TYPE values)
97 DriverExtension->IsLegacyDriver = FALSE;
98 ZwClose(parametersKey);
99 }
100 }
101}
102
103/**********************************************************************
104 * NAME INTERNAL
105 * SpiBuildDeviceMap
106 *
107 * DESCRIPTION
108 * Builds the registry device map of all device which are attached
109 * to the given SCSI HBA port. The device map is located at:
110 * \Registry\Machine\DeviceMap\Scsi
111 *
112 * RUN LEVEL
113 * PASSIVE_LEVEL
114 *
115 * ARGUMENTS
116 * DeviceExtension
117 * ...
118 *
119 * RegistryPath
120 * Name of registry driver service key.
121 *
122 * RETURNS
123 * NTSTATUS
124 */
125
128 _Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
129{
133 WCHAR NameBuffer[64];
134 HANDLE ScsiKey;
135 HANDLE ScsiPortKey = NULL;
136 HANDLE ScsiBusKey = NULL;
137 HANDLE ScsiInitiatorKey = NULL;
139 ULONG UlongData;
141
142 DPRINT("SpiBuildDeviceMap() called\n");
143
144 if (DeviceExtension == NULL)
145 {
146 DPRINT1("Invalid parameter\n");
148 }
149
150 /* Open or create the 'Scsi' subkey */
152 L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
154 &KeyName,
156 0,
157 NULL);
158 Status = ZwCreateKey(&ScsiKey,
161 0,
162 NULL,
164 NULL);
165 if (!NT_SUCCESS(Status))
166 {
167 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
168 return Status;
169 }
170
171 /* Create new 'Scsi Port X' subkey */
172 DPRINT("Scsi Port %lu\n", DeviceExtension->PortNumber);
173
174 swprintf(NameBuffer,
175 L"Scsi Port %lu",
176 DeviceExtension->PortNumber);
177 RtlInitUnicodeString(&KeyName, NameBuffer);
179 Status = ZwCreateKey(&ScsiPortKey,
182 0,
183 NULL,
185 NULL);
186 ZwClose(ScsiKey);
187 if (!NT_SUCCESS(Status))
188 {
189 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
190 return Status;
191 }
192
193 /*
194 * Create port-specific values
195 */
196
197 /* Set 'DMA Enabled' (REG_DWORD) value */
198 UlongData = (ULONG)!DeviceExtension->PortCapabilities.AdapterUsesPio;
199 DPRINT(" DMA Enabled = %s\n", UlongData ? "TRUE" : "FALSE");
200 RtlInitUnicodeString(&ValueName, L"DMA Enabled");
201 Status = ZwSetValueKey(ScsiPortKey,
202 &ValueName,
203 0,
204 REG_DWORD,
205 &UlongData,
206 sizeof(UlongData));
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
210 ZwClose(ScsiPortKey);
211 return Status;
212 }
213
214 /* Set 'Driver' (REG_SZ) value */
215 PUNICODE_STRING driverNameU = &DeviceExtension->Common.DeviceObject->DriverObject
216 ->DriverExtension->ServiceKeyName;
217
219 driverNameU->Length + sizeof(UNICODE_NULL),
221 if (!driverName)
222 {
223 DPRINT("Failed to allocate driverName!\n");
224 ZwClose(ScsiPortKey);
226 }
227
228 RtlCopyMemory(driverName, driverNameU->Buffer, driverNameU->Length);
229 driverName[driverNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
230
232 Status = ZwSetValueKey(ScsiPortKey,
233 &ValueName,
234 0,
235 REG_SZ,
236 driverName,
237 driverNameU->Length + sizeof(UNICODE_NULL));
238
239 ExFreePoolWithTag(driverName, TAG_SCSIPORT);
240
241 if (!NT_SUCCESS(Status))
242 {
243 DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
244 ZwClose(ScsiPortKey);
245 return Status;
246 }
247
248 /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
249 UlongData = (ULONG)DeviceExtension->PortConfig->BusInterruptLevel;
250 DPRINT(" Interrupt = %lu\n", UlongData);
251 RtlInitUnicodeString(&ValueName, L"Interrupt");
252 Status = ZwSetValueKey(ScsiPortKey,
253 &ValueName,
254 0,
255 REG_DWORD,
256 &UlongData,
257 sizeof(UlongData));
258 if (!NT_SUCCESS(Status))
259 {
260 DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
261 ZwClose(ScsiPortKey);
262 return Status;
263 }
264
265 /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
266 UlongData = ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension->PortConfig->AccessRanges)[0].RangeStart);
267 DPRINT(" IOAddress = %lx\n", UlongData);
268 RtlInitUnicodeString(&ValueName, L"IOAddress");
269 Status = ZwSetValueKey(ScsiPortKey,
270 &ValueName,
271 0,
272 REG_DWORD,
273 &UlongData,
274 sizeof(UlongData));
275 if (!NT_SUCCESS(Status))
276 {
277 DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
278 ZwClose(ScsiPortKey);
279 return Status;
280 }
281
282 /* Enumerate buses */
283 for (BusNumber = 0; BusNumber < DeviceExtension->NumberOfBuses; BusNumber++)
284 {
285 /* Create 'Scsi Bus X' key */
286 DPRINT(" Scsi Bus %lu\n", BusNumber);
287 swprintf(NameBuffer,
288 L"Scsi Bus %lu",
289 BusNumber);
290 RtlInitUnicodeString(&KeyName, NameBuffer);
292 &KeyName,
294 ScsiPortKey,
295 NULL);
296 Status = ZwCreateKey(&ScsiBusKey,
299 0,
300 NULL,
302 NULL);
303 if (!NT_SUCCESS(Status))
304 {
305 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
306 goto ByeBye;
307 }
308
309 /* Create 'Initiator Id X' key */
310 DPRINT(" Initiator Id %lu\n",
311 DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
312 swprintf(NameBuffer,
313 L"Initiator Id %lu",
314 (ULONG)(UCHAR)DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
315 RtlInitUnicodeString(&KeyName, NameBuffer);
317 &KeyName,
319 ScsiBusKey,
320 NULL);
321 Status = ZwCreateKey(&ScsiInitiatorKey,
324 0,
325 NULL,
327 NULL);
328 if (!NT_SUCCESS(Status))
329 {
330 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
331 goto ByeBye;
332 }
333
334 /* FIXME: Are there any initiator values (??) */
335
336 ZwClose(ScsiInitiatorKey);
337 ScsiInitiatorKey = NULL;
338
339 DeviceExtension->Buses[BusNumber].RegistryMapKey = ScsiBusKey;
340 ScsiBusKey = NULL;
341 }
342
343ByeBye:
344 if (ScsiInitiatorKey != NULL)
345 ZwClose(ScsiInitiatorKey);
346
347 if (ScsiBusKey != NULL)
348 ZwClose(ScsiBusKey);
349
350 if (ScsiPortKey != NULL)
351 ZwClose(ScsiPortKey);
352
353 DPRINT("SpiBuildDeviceMap() done\n");
354
355 return Status;
356}
357
361{
362 WCHAR nameBuffer[64];
363 UNICODE_STRING keyName;
364 UNICODE_STRING valueName;
365 OBJECT_ATTRIBUTES objectAttributes;
366 HANDLE targetKey;
368
369 // get the LUN's bus key
370 PSCSI_PORT_DEVICE_EXTENSION portExt = LunExtension->Common.LowerDevice->DeviceExtension;
371 HANDLE busKey = portExt->Buses[LunExtension->PathId].RegistryMapKey;
372
373 // create/open 'Target Id X' key
374 swprintf(nameBuffer, L"Target Id %lu", LunExtension->TargetId);
375 RtlInitUnicodeString(&keyName, nameBuffer);
376 InitializeObjectAttributes(&objectAttributes, &keyName, OBJ_KERNEL_HANDLE, busKey, NULL);
377 status = ZwCreateKey(&targetKey,
379 &objectAttributes,
380 0,
381 NULL,
383 NULL);
384 if (!NT_SUCCESS(status))
385 {
386 DPRINT("ZwCreateKey() failed (Status %lx)\n", status);
387 return status;
388 }
389
390 // Create 'Logical Unit Id X' key
391 swprintf(nameBuffer, L"Logical Unit Id %lu", LunExtension->Lun);
392 RtlInitUnicodeString(&keyName, nameBuffer);
393 InitializeObjectAttributes(&objectAttributes, &keyName, OBJ_KERNEL_HANDLE, targetKey, NULL);
394 status = ZwCreateKey(&LunExtension->RegistryMapKey,
396 &objectAttributes,
397 0,
398 NULL,
400 NULL);
401 if (!NT_SUCCESS(status))
402 {
403 DPRINT("ZwCreateKey() failed (Status %lx)\n", status);
404 goto ByeBye;
405 }
406
407 // Set 'Identifier' (REG_SZ) value
408 swprintf(nameBuffer,
409 L"%.8S%.16S%.4S",
410 LunExtension->InquiryData.VendorId,
411 LunExtension->InquiryData.ProductId,
412 LunExtension->InquiryData.ProductRevisionLevel);
413 RtlInitUnicodeString(&valueName, L"Identifier");
414 status = ZwSetValueKey(LunExtension->RegistryMapKey,
415 &valueName,
416 0,
417 REG_SZ,
418 nameBuffer,
419 (wcslen(nameBuffer) + 1) * sizeof(WCHAR));
420 if (!NT_SUCCESS(status))
421 {
422 DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", status);
423 goto ByeBye;
424 }
425
426 // Set 'Type' (REG_SZ) value
427 PWCHAR typeName = (PWCHAR)GetPeripheralTypeW(&LunExtension->InquiryData);
428 DPRINT(" Type = '%S'\n", typeName);
429 RtlInitUnicodeString(&valueName, L"Type");
430 status = ZwSetValueKey(LunExtension->RegistryMapKey,
431 &valueName,
432 0,
433 REG_SZ,
434 typeName,
435 (wcslen(typeName) + 1) * sizeof(WCHAR));
436 if (!NT_SUCCESS(status))
437 {
438 DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", status);
439 goto ByeBye;
440 }
441
442 // Set 'InquiryData' (REG_BINARY) value
443 RtlInitUnicodeString(&valueName, L"InquiryData");
444 status = ZwSetValueKey(LunExtension->RegistryMapKey,
445 &valueName,
446 0,
448 &LunExtension->InquiryData,
450 if (!NT_SUCCESS(status))
451 {
452 DPRINT("ZwSetValueKey('InquiryData') failed (Status %lx)\n", status);
453 goto ByeBye;
454 }
455
456ByeBye:
457 ZwClose(targetKey);
458 // TODO: maybe we will need it in future
459 ZwClose(LunExtension->RegistryMapKey);
460
461 return status;
462}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define swprintf
Definition: precomp.h:40
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:957
VOID SpiInitOpenKeys(_Inout_ PCONFIGURATION_INFO ConfigInfo, _In_ PSCSI_PORT_DRIVER_EXTENSION DriverExtension)
Definition: registry.c:18
NTSTATUS RegistryInitAdapterKey(_Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: registry.c:127
NTSTATUS RegistryInitLunKey(_Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension)
Definition: registry.c:359
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
#define TAG_SCSIPORT
Definition: scsiport.h:21
FORCEINLINE PCWSTR GetPeripheralTypeW(_In_ PINQUIRYDATA InquiryData)
Definition: scsitypes.h:87
#define REG_DWORD
Definition: sdbapi.c:596
#define DPRINT
Definition: sndvol32.h:73
Definition: ps.c:97
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180