ReactOS  0.4.14-dev-297-g23e575c
findscsi.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Storage Stack
3  * LICENSE: DDK - see license.txt in the root dir
4  * FILE: drivers/storage/cdrom/cdrom.c
5  * PURPOSE: CDROM driver
6  * PROGRAMMERS: Based on a source code sample from Microsoft NT4 DDK
7  */
8 
9 #include "precomp.h"
10 
11 //#define NDEBUG
12 #include <debug.h>
13 
15 NTAPI
18  IN UNICODE_STRING ScsiUnicodeString[],
19  OUT PUCHAR IntermediateController
20  );
21 
22 #define INIT_OPEN_KEY(name, rootHandle, pNewHandle) \
23  InitializeObjectAttributes( \
24  &objectAttributes, \
25  (name), \
26  OBJ_CASE_INSENSITIVE, \
27  (rootHandle), \
28  NULL \
29  ); \
30  \
31  status = ZwOpenKey( \
32  (pNewHandle), \
33  KEY_READ | KEY_ENUMERATE_SUB_KEYS, \
34  &objectAttributes \
35  );
36 
37 
39 NTAPI
42  IN UNICODE_STRING ScsiUnicodeString[],
43  OUT UCHAR *IntermediateController
44  )
45 
46 /*++
47 
48  Routine Description:
49 
50  Recursive routine to walk registry tree under KeyHandle looking for
51  location of ScsiAdapter and other valid controllers that the ScsiAdapter
52  might hang off of. When ScsiAdapter is found, FindScsiAdapter
53  returns an ARC name for the intervening controller(s) between the
54  original key and ScsiAdapter.
55 
56  Arguments:
57 
58  KeyHandle -- Handle of open registry key (somewhere under
59  \Registry\Machine\Hardware\Description\System)
60 
61  ScsiUnicodeString -- NT name of SCSI device being sought in the registry
62 
63  IntermediateController -- Null terminated buffer which this routine fills with
64  ARC name for intervening controller(s). Null is returned
65  if ScsiAdapter sits at the root or if it is not found.
66 
67  Return Value:
68 
69  STATUS_SUCCESS -- IntermediateController set to something like multi(1)
70 
71  STATUS_OBJECT_PATH_NOT_FOUND -- all ok, but no ScsiAdapter
72  (with correct scsi id & lun info) found; In this case
73  IntermediateController is explicitly set to null.
74 
75  Other status codes as returned by open\enumerate registry routines
76  may also be returned.
77 
78 --*/
79 
80 {
81 #if 0
83  ULONG index;
84  ULONG resultLength;
85  UCHAR lowerController[64];
86  BOOLEAN validControllerNumber;
87  UNICODE_STRING unicodeString[64];
88  OBJECT_ATTRIBUTES objectAttributes;
89 
90  HANDLE controllerHandle;
91  HANDLE controllerNumberHandle;
92  ULONG controllerIndex;
93  ULONG controllerNumberIndex;
94  UCHAR keyBuffer[256]; // Allow for variable length name at end
95  UCHAR numberKeyBuffer[64];
96  PKEY_BASIC_INFORMATION pControllerKeyInformation;
97  PKEY_BASIC_INFORMATION pControllerNumberKeyInformation;
98 
99  // TODO: Any PAGED_CODE stuff...
100 
101  //
102  // Walk enumerated subkeys, looking for valid controllers
103  //
104 
105  for (controllerIndex = 0; TRUE; controllerIndex++) {
106 
107  //
108  // Ensure pControllerKeyInformation->Name is null terminated
109  //
110 
111  RtlZeroMemory(keyBuffer, sizeof(keyBuffer));
112 
113  pControllerKeyInformation = (PKEY_BASIC_INFORMATION) keyBuffer;
114 
115  status = ZwEnumerateKey(
116  KeyHandle,
117  controllerIndex,
119  pControllerKeyInformation,
120  sizeof(keyBuffer),
121  &resultLength
122  );
123 
124  if (!NT_SUCCESS(status)) {
125 
127  DebugPrint ((2, "FindScsiAdapter: Error 0x%x enumerating key\n", status));
128  return(status);
129  }
130 
131  break; // return NOT_FOUND
132  }
133 
134  DebugPrint ((3, "FindScsiAdapter: Found Adapter=%S\n", pControllerKeyInformation->Name));
135 
136  if (!_wcsicmp(pControllerKeyInformation->Name, L"ScsiAdapter")) {
137 
138  //
139  // Found scsi, now verify that it's the same one we're trying to initialize.
140  //
141 
142  INIT_OPEN_KEY (ScsiUnicodeString, KeyHandle, &controllerHandle);
143 
144  ZwClose(controllerHandle);
145 
146  if (NT_SUCCESS(status)) {
147 
148  //
149  // Found correct scsi, now build ARC name of IntermediateController
150  // (i.e. the intervening controllers, or everything above ScsiAdapter)
151  // start with null, and build string one controller at a time as we
152  // return up the recursively called routine.
153  //
154 
155  IntermediateController = "\0";
156 
157  return (STATUS_SUCCESS);
158  }
159 
160  //
161  // Found ScsiAdapter, but wrong scsi id or Lun info doesn't match,
162  // (ignore other ZwOpenKey errors &) keep looking...
163  //
164 
165  }
166 
167  else if (!_wcsicmp(pControllerKeyInformation->Name, L"MultifunctionAdapter") ||
168  !_wcsicmp(pControllerKeyInformation->Name, L"EisaAdapter")) {
169 
170  //
171  // This is a valid controller that may have ScsiAdapter beneath it.
172  // Open controller & walk controller's subkeys: 0, 1, 2, etc....
173  //
174 
175  RtlInitUnicodeString (unicodeString, pControllerKeyInformation->Name);
176 
177  INIT_OPEN_KEY (unicodeString, KeyHandle, &controllerHandle);
178 
179  if (!NT_SUCCESS(status)) {
180  DebugPrint ((2, "FindScsiAdapter: ZwOpenKey got status = %x \n", status));
181  ZwClose (controllerHandle);
182  return (status);
183  }
184 
185 
186 
187  for (controllerNumberIndex = 0; TRUE; controllerNumberIndex++) {
188 
189  RtlZeroMemory(numberKeyBuffer, sizeof(numberKeyBuffer));
190 
191  pControllerNumberKeyInformation = (PKEY_BASIC_INFORMATION) numberKeyBuffer;
192 
193  status = ZwEnumerateKey(
194  controllerHandle,
195  controllerNumberIndex,
197  pControllerNumberKeyInformation,
198  sizeof(numberKeyBuffer),
199  &resultLength
200  );
201 
202  if (!NT_SUCCESS(status)) {
203 
205  DebugPrint ((2, "FindScsiAdapter: Status %x enumerating key\n", status));
206  ZwClose(controllerHandle);
207  return (status);
208  }
209 
210  ZwClose(controllerHandle);
211 
212  break; // next controller
213  }
214 
215  DebugPrint ((3, "FindScsiAdapter: Found Adapter #=%S\n", pControllerNumberKeyInformation->Name));
216 
217  validControllerNumber = TRUE;
218 
219  for (index = 0; index < pControllerNumberKeyInformation->NameLength / 2; index++) {
220 
221  if (!isxdigit(pControllerNumberKeyInformation->Name[index])) {
222  validControllerNumber = FALSE;
223  break;
224  }
225 
226  }
227 
228  if (validControllerNumber) {
229 
230  //
231  // Found valid controller and controller number: check children for scsi.
232  //
233 
234  RtlInitUnicodeString (unicodeString, pControllerNumberKeyInformation->Name);
235 
236  INIT_OPEN_KEY (unicodeString, controllerHandle, &controllerNumberHandle);
237 
238  if (!NT_SUCCESS(status)) {
239  DebugPrint ((2, "FindScsiAdapter: Status %x opening controller number key\n", status));
240  ZwClose(controllerNumberHandle);
241  ZwClose(controllerHandle);
242  return (status);
243  }
244 
245  RtlZeroMemory(lowerController, sizeof(lowerController));
246 
248  controllerNumberHandle,
249  ScsiUnicodeString,
250  &lowerController[0]
251  );
252 
253  ZwClose(controllerNumberHandle);
254 
255  if (NT_SUCCESS(status)) {
256 
257  //
258  // SUCCESS!
259  //
260  // Scsi adapter DOES exist under this node,
261  // prepend Arc Name for the current adapter to whatever was returned
262  // by other calls to this routine.
263  //
264 
265  if (!_wcsicmp(pControllerKeyInformation->Name, L"MultifunctionAdapter")) {
266  sprintf(IntermediateController, "multi(0)%s", lowerController);
267  } else {
268  sprintf(IntermediateController, "eisa(0)%s", lowerController);
269  }
270 
271  ZwClose(controllerHandle);
272 
273  return(STATUS_SUCCESS);
274  }
275 
276  else if (status != STATUS_OBJECT_PATH_NOT_FOUND) {
277  ZwClose(controllerHandle);
278  return(status);
279  }
280 
281  //
282  // Scsi not found under this controller number, check next one
283  //
284 
285  } // if validControllerNumber
286 
287  } // for controllerNumberIndex
288 
289 
290 
291  //
292  // ScsiAdapter not found under this controller
293  //
294 
295  ZwClose(controllerHandle);
296 
297  } // else if valid subkey (i.e., scsi, multi, eisa)
298 
299  } // for controllerIndex
300 
301  //
302  // ScsiAdapter not found under key we were called with
303  //
304 
305  IntermediateController = "\0";
306 #endif
308 }
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _KEY_BASIC_INFORMATION * PKEY_BASIC_INFORMATION
unsigned char BOOLEAN
NTSTATUS NTAPI FindScsiAdapter(IN HANDLE KeyHandle, IN UNICODE_STRING ScsiUnicodeString[], OUT PUCHAR IntermediateController)
Definition: findscsi.c:40
GLuint index
Definition: glext.h:6031
#define INIT_OPEN_KEY(name, rootHandle, pNewHandle)
Definition: findscsi.c:22
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
unsigned char UCHAR
Definition: xmlstorage.h:181
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define isxdigit(c)
Definition: acclib.h:70
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2966
static SERVICE_STATUS status
Definition: service.c:31
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Definition: ps.c:97