ReactOS  0.4.15-dev-1374-g8d3e80e
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  */
8 
9 #include "scsiport.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 
15 VOID
17  _Inout_ PCONFIGURATION_INFO ConfigInfo,
19 {
23 
24  /* Open the service key */
28  NULL,
29  NULL);
30 
31  Status = ZwOpenKey(&ConfigInfo->ServiceKey,
32  KEY_READ,
34 
35  if (!NT_SUCCESS(Status))
36  {
37  DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath, Status);
38  ConfigInfo->ServiceKey = NULL;
39  }
40 
41  /* If we could open driver's service key, then proceed to the Parameters key */
42  if (ConfigInfo->ServiceKey != NULL)
43  {
44  RtlInitUnicodeString(&KeyName, L"Parameters");
46  &KeyName,
48  ConfigInfo->ServiceKey,
50 
51  /* Try to open it */
52  Status = ZwOpenKey(&ConfigInfo->DeviceKey,
53  KEY_READ,
55 
56  if (NT_SUCCESS(Status))
57  {
58  /* Yes, Parameters key exist, and it must be used instead of
59  the Service key */
60  ZwClose(ConfigInfo->ServiceKey);
61  ConfigInfo->ServiceKey = ConfigInfo->DeviceKey;
62  ConfigInfo->DeviceKey = NULL;
63  }
64  }
65 
66  if (ConfigInfo->ServiceKey != NULL)
67  {
68  /* Open the Device key */
69  RtlInitUnicodeString(&KeyName, L"Device");
71  &KeyName,
73  ConfigInfo->ServiceKey,
74  NULL);
75 
76  /* We don't check for failure here - not needed */
77  ZwOpenKey(&ConfigInfo->DeviceKey,
78  KEY_READ,
80  }
81 }
82 
83 /**********************************************************************
84  * NAME INTERNAL
85  * SpiBuildDeviceMap
86  *
87  * DESCRIPTION
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
91  *
92  * RUN LEVEL
93  * PASSIVE_LEVEL
94  *
95  * ARGUMENTS
96  * DeviceExtension
97  * ...
98  *
99  * RegistryPath
100  * Name of registry driver service key.
101  *
102  * RETURNS
103  * NTSTATUS
104  */
105 
106 NTSTATUS
108  _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
110 {
111  PSCSI_PORT_LUN_EXTENSION LunExtension;
115  WCHAR NameBuffer[64];
117  HANDLE ScsiKey;
118  HANDLE ScsiPortKey = NULL;
119  HANDLE ScsiBusKey = NULL;
120  HANDLE ScsiInitiatorKey = NULL;
121  HANDLE ScsiTargetKey = NULL;
122  HANDLE ScsiLunKey = NULL;
124  ULONG Target;
125  ULONG CurrentTarget;
126  ULONG Lun;
127  PWCHAR DriverName;
128  ULONG UlongData;
129  PWCHAR TypeName;
131 
132  DPRINT("SpiBuildDeviceMap() called\n");
133 
134  if (DeviceExtension == NULL || RegistryPath == NULL)
135  {
136  DPRINT1("Invalid parameter\n");
138  }
139 
140  /* Open or create the 'Scsi' subkey */
142  L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
144  &KeyName,
146  0,
147  NULL);
148  Status = ZwCreateKey(&ScsiKey,
151  0,
152  NULL,
154  &Disposition);
155  if (!NT_SUCCESS(Status))
156  {
157  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
158  return Status;
159  }
160 
161  /* Create new 'Scsi Port X' subkey */
162  DPRINT("Scsi Port %lu\n", DeviceExtension->PortNumber);
163 
164  swprintf(NameBuffer,
165  L"Scsi Port %lu",
166  DeviceExtension->PortNumber);
167  RtlInitUnicodeString(&KeyName, NameBuffer);
169  &KeyName,
171  ScsiKey,
172  NULL);
173  Status = ZwCreateKey(&ScsiPortKey,
176  0,
177  NULL,
179  &Disposition);
180  ZwClose(ScsiKey);
181  if (!NT_SUCCESS(Status))
182  {
183  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
184  return Status;
185  }
186 
187  /*
188  * Create port-specific values
189  */
190 
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,
196  &ValueName,
197  0,
198  REG_DWORD,
199  &UlongData,
200  sizeof(UlongData));
201  if (!NT_SUCCESS(Status))
202  {
203  DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
204  ZwClose(ScsiPortKey);
205  return Status;
206  }
207 
208  /* Set 'Driver' (REG_SZ) value */
209  DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1;
210  RtlInitUnicodeString(&ValueName, L"Driver");
211  Status = ZwSetValueKey(ScsiPortKey,
212  &ValueName,
213  0,
214  REG_SZ,
215  DriverName,
216  (ULONG)((wcslen(DriverName) + 1) * sizeof(WCHAR)));
217  if (!NT_SUCCESS(Status))
218  {
219  DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
220  ZwClose(ScsiPortKey);
221  return Status;
222  }
223 
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,
229  &ValueName,
230  0,
231  REG_DWORD,
232  &UlongData,
233  sizeof(UlongData));
234  if (!NT_SUCCESS(Status))
235  {
236  DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
237  ZwClose(ScsiPortKey);
238  return Status;
239  }
240 
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,
246  &ValueName,
247  0,
248  REG_DWORD,
249  &UlongData,
250  sizeof(UlongData));
251  if (!NT_SUCCESS(Status))
252  {
253  DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
254  ZwClose(ScsiPortKey);
255  return Status;
256  }
257 
258  /* Enumerate buses */
259  for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig->NumberOfBuses; BusNumber++)
260  {
261  /* Create 'Scsi Bus X' key */
262  DPRINT(" Scsi Bus %lu\n", BusNumber);
263  swprintf(NameBuffer,
264  L"Scsi Bus %lu",
265  BusNumber);
266  RtlInitUnicodeString(&KeyName, NameBuffer);
268  &KeyName,
269  0,
270  ScsiPortKey,
271  NULL);
272  Status = ZwCreateKey(&ScsiBusKey,
275  0,
276  NULL,
278  &Disposition);
279  if (!NT_SUCCESS(Status))
280  {
281  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
282  goto ByeBye;
283  }
284 
285  /* Create 'Initiator Id X' key */
286  DPRINT(" Initiator Id %lu\n",
287  DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
288  swprintf(NameBuffer,
289  L"Initiator Id %lu",
290  (ULONG)(UCHAR)DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
291  RtlInitUnicodeString(&KeyName, NameBuffer);
293  &KeyName,
294  0,
295  ScsiBusKey,
296  NULL);
297  Status = ZwCreateKey(&ScsiInitiatorKey,
300  0,
301  NULL,
303  &Disposition);
304  if (!NT_SUCCESS(Status))
305  {
306  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
307  goto ByeBye;
308  }
309 
310  /* FIXME: Are there any initiator values (??) */
311 
312  ZwClose(ScsiInitiatorKey);
313  ScsiInitiatorKey = NULL;
314 
315 
316  /* Enumerate targets */
317  CurrentTarget = (ULONG)-1;
318  ScsiTargetKey = NULL;
319  for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
320  {
321  for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
322  {
323  LunExtension = SpiGetLunExtension(DeviceExtension,
324  (UCHAR)BusNumber,
325  (UCHAR)Target,
326  (UCHAR)Lun);
327  if (LunExtension == NULL)
328  continue;
329 
330  if (Target != CurrentTarget)
331  {
332  /* Close old target key */
333  if (ScsiTargetKey != NULL)
334  {
335  ZwClose(ScsiTargetKey);
336  ScsiTargetKey = NULL;
337  }
338 
339  /* Create 'Target Id X' key */
340  DPRINT(" Target Id %lu\n", Target);
341  swprintf(NameBuffer,
342  L"Target Id %lu",
343  Target);
344  RtlInitUnicodeString(&KeyName, NameBuffer);
346  &KeyName,
347  0,
348  ScsiBusKey,
349  NULL);
350  Status = ZwCreateKey(&ScsiTargetKey,
353  0,
354  NULL,
356  &Disposition);
357  if (!NT_SUCCESS(Status))
358  {
359  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
360  goto ByeBye;
361  }
362 
363  CurrentTarget = Target;
364  }
365 
366  /* Create 'Logical Unit Id X' key */
367  DPRINT(" Logical Unit Id %lu\n", Lun);
368  swprintf(NameBuffer,
369  L"Logical Unit Id %lu",
370  Lun);
371  RtlInitUnicodeString(&KeyName, NameBuffer);
373  &KeyName,
374  0,
375  ScsiTargetKey,
376  NULL);
377  Status = ZwCreateKey(&ScsiLunKey,
380  0,
381  NULL,
383  &Disposition);
384  if (!NT_SUCCESS(Status))
385  {
386  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
387  goto ByeBye;
388  }
389 
390  /* Set 'Identifier' (REG_SZ) value */
391  swprintf(NameBuffer,
392  L"%.8S%.16S%.4S",
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,
399  &ValueName,
400  0,
401  REG_SZ,
402  NameBuffer,
403  (ULONG)((wcslen(NameBuffer) + 1) * sizeof(WCHAR)));
404  if (!NT_SUCCESS(Status))
405  {
406  DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status);
407  goto ByeBye;
408  }
409 
410  /* Set 'Type' (REG_SZ) value */
411  /*
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.
415  */
416  switch (LunExtension->InquiryData.DeviceType)
417  {
418  case 0:
419  TypeName = L"DiskPeripheral";
420  break;
421  case 1:
422  TypeName = L"TapePeripheral";
423  break;
424  case 2:
425  TypeName = L"PrinterPeripheral";
426  break;
427  // case 3: "ProcessorPeripheral", classified as 'other': fall back to default case.
428  case 4:
429  TypeName = L"WormPeripheral";
430  break;
431  case 5:
432  TypeName = L"CdRomPeripheral";
433  break;
434  case 6:
435  TypeName = L"ScannerPeripheral";
436  break;
437  case 7:
438  TypeName = L"OpticalDiskPeripheral";
439  break;
440  case 8:
441  TypeName = L"MediumChangerPeripheral";
442  break;
443  case 9:
444  TypeName = L"CommunicationsPeripheral";
445  break;
446 
447  /* New peripheral types (SCSI only) */
448  case 10: case 11:
449  TypeName = L"ASCPrePressGraphicsPeripheral";
450  break;
451  case 12:
452  TypeName = L"ArrayPeripheral";
453  break;
454  case 13:
455  TypeName = L"EnclosurePeripheral";
456  break;
457  case 14:
458  TypeName = L"RBCPeripheral";
459  break;
460  case 15:
461  TypeName = L"CardReaderPeripheral";
462  break;
463  case 16:
464  TypeName = L"BridgePeripheral";
465  break;
466 
467  default:
468  TypeName = L"OtherPeripheral";
469  break;
470  }
471  DPRINT(" Type = '%S'\n", TypeName);
473  Status = ZwSetValueKey(ScsiLunKey,
474  &ValueName,
475  0,
476  REG_SZ,
477  TypeName,
478  (ULONG)((wcslen(TypeName) + 1) * sizeof(WCHAR)));
479  if (!NT_SUCCESS(Status))
480  {
481  DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
482  goto ByeBye;
483  }
484 
485  ZwClose(ScsiLunKey);
486  ScsiLunKey = NULL;
487  }
488 
489  /* Close old target key */
490  if (ScsiTargetKey != NULL)
491  {
492  ZwClose(ScsiTargetKey);
493  ScsiTargetKey = NULL;
494  }
495  }
496 
497  ZwClose(ScsiBusKey);
498  ScsiBusKey = NULL;
499  }
500 
501 ByeBye:
502  if (ScsiLunKey != NULL)
503  ZwClose(ScsiLunKey);
504 
505  if (ScsiInitiatorKey != NULL)
506  ZwClose(ScsiInitiatorKey);
507 
508  if (ScsiTargetKey != NULL)
509  ZwClose(ScsiTargetKey);
510 
511  if (ScsiBusKey != NULL)
512  ZwClose(ScsiBusKey);
513 
514  if (ScsiPortKey != NULL)
515  ZwClose(ScsiPortKey);
516 
517  DPRINT("SpiBuildDeviceMap() done\n");
518 
519  return Status;
520 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define KEY_READ
Definition: nt_native.h:1023
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:57
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
uint16_t * PWCHAR
Definition: typedefs.h:56
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define OBJ_OPENIF
Definition: winternl.h:229
NTSTATUS SpiBuildDeviceMap(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ PUNICODE_STRING RegistryPath)
Definition: registry.c:107
void DPRINT(...)
Definition: polytest.cpp:61
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2697
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define _Inout_
Definition: no_sal2.h:162
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:240
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define wcsrchr
Definition: compat.h:16
#define _In_
Definition: no_sal2.h:158
UCHAR DeviceType
Definition: cdrw_hw.h:1116
INQUIRYDATA InquiryData
Definition: scsiport.h:131
VOID SpiInitOpenKeys(_Inout_ PCONFIGURATION_INFO ConfigInfo, _In_ PUNICODE_STRING RegistryPath)
Definition: registry.c:16
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define NULL
Definition: types.h:112
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define REG_DWORD
Definition: sdbapi.c:596
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22