mirror of
https://github.com/reactos/reactos.git
synced 2024-08-25 04:38:43 +00:00
309 lines
9.8 KiB
C
309 lines
9.8 KiB
C
/*
|
||
* PROJECT: ReactOS Storage Stack
|
||
* LICENSE: DDK - see license.txt in the root dir
|
||
* FILE: drivers/storage/cdrom/cdrom.c
|
||
* PURPOSE: CDROM driver
|
||
* PROGRAMMERS: Based on a source code sample from Microsoft NT4 DDK
|
||
*/
|
||
|
||
#include "precomp.h"
|
||
|
||
//#define NDEBUG
|
||
#include <debug.h>
|
||
|
||
NTSTATUS
|
||
NTAPI
|
||
FindScsiAdapter (
|
||
IN HANDLE KeyHandle,
|
||
IN UNICODE_STRING ScsiUnicodeString[],
|
||
OUT PUCHAR IntermediateController
|
||
);
|
||
|
||
#define INIT_OPEN_KEY(name, rootHandle, pNewHandle) \
|
||
InitializeObjectAttributes( \
|
||
&objectAttributes, \
|
||
(name), \
|
||
OBJ_CASE_INSENSITIVE, \
|
||
(rootHandle), \
|
||
NULL \
|
||
); \
|
||
\
|
||
status = ZwOpenKey( \
|
||
(pNewHandle), \
|
||
KEY_READ | KEY_ENUMERATE_SUB_KEYS, \
|
||
&objectAttributes \
|
||
);
|
||
|
||
|
||
NTSTATUS
|
||
NTAPI
|
||
FindScsiAdapter (
|
||
IN HANDLE KeyHandle,
|
||
IN UNICODE_STRING ScsiUnicodeString[],
|
||
OUT UCHAR *IntermediateController
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Recursive routine to walk registry tree under KeyHandle looking for
|
||
location of ScsiAdapter and other valid controllers that the ScsiAdapter
|
||
might hang off of. When ScsiAdapter is found, FindScsiAdapter
|
||
returns an ARC name for the intervening controller(s) between the
|
||
original key and ScsiAdapter.
|
||
|
||
Arguments:
|
||
|
||
KeyHandle -- Handle of open registry key (somewhere under
|
||
\Registry\Machine\Hardware\Description\System)
|
||
|
||
ScsiUnicodeString -- NT name of SCSI device being sought in the registry
|
||
|
||
IntermediateController -- Null terminated buffer which this routine fills with
|
||
ARC name for intervening controller(s). Null is returned
|
||
if ScsiAdapter sits at the root or if it is not found.
|
||
|
||
Return Value:
|
||
|
||
STATUS_SUCCESS -- IntermediateController set to something like multi(1)
|
||
|
||
STATUS_OBJECT_PATH_NOT_FOUND -- all ok, but no ScsiAdapter
|
||
(with correct scsi id & lun info) found; In this case
|
||
IntermediateController is explicitly set to null.
|
||
|
||
Other status codes as returned by open\enumerate registry routines
|
||
may also be returned.
|
||
|
||
--*/
|
||
|
||
{
|
||
#if 0
|
||
NTSTATUS status;
|
||
ULONG index;
|
||
ULONG resultLength;
|
||
UCHAR lowerController[64];
|
||
BOOLEAN validControllerNumber;
|
||
UNICODE_STRING unicodeString[64];
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
|
||
HANDLE controllerHandle;
|
||
HANDLE controllerNumberHandle;
|
||
ULONG controllerIndex;
|
||
ULONG controllerNumberIndex;
|
||
UCHAR keyBuffer[256]; // Allow for variable length name at end
|
||
UCHAR numberKeyBuffer[64];
|
||
PKEY_BASIC_INFORMATION pControllerKeyInformation;
|
||
PKEY_BASIC_INFORMATION pControllerNumberKeyInformation;
|
||
|
||
// TODO: Any PAGED_CODE stuff...
|
||
|
||
//
|
||
// Walk enumerated subkeys, looking for valid controllers
|
||
//
|
||
|
||
for (controllerIndex = 0; TRUE; controllerIndex++) {
|
||
|
||
//
|
||
// Ensure pControllerKeyInformation->Name is null terminated
|
||
//
|
||
|
||
RtlZeroMemory(keyBuffer, sizeof(keyBuffer));
|
||
|
||
pControllerKeyInformation = (PKEY_BASIC_INFORMATION) keyBuffer;
|
||
|
||
status = ZwEnumerateKey(
|
||
KeyHandle,
|
||
controllerIndex,
|
||
KeyBasicInformation,
|
||
pControllerKeyInformation,
|
||
sizeof(keyBuffer),
|
||
&resultLength
|
||
);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
if (status != STATUS_NO_MORE_ENTRIES) {
|
||
DebugPrint ((2, "FindScsiAdapter: Error 0x%x enumerating key\n", status));
|
||
return(status);
|
||
}
|
||
|
||
break; // return NOT_FOUND
|
||
}
|
||
|
||
DebugPrint ((3, "FindScsiAdapter: Found Adapter=%S\n", pControllerKeyInformation->Name));
|
||
|
||
if (!_wcsicmp(pControllerKeyInformation->Name, L"ScsiAdapter")) {
|
||
|
||
//
|
||
// Found scsi, now verify that it's the same one we're trying to initialize.
|
||
//
|
||
|
||
INIT_OPEN_KEY (ScsiUnicodeString, KeyHandle, &controllerHandle);
|
||
|
||
ZwClose(controllerHandle);
|
||
|
||
if (NT_SUCCESS(status)) {
|
||
|
||
//
|
||
// Found correct scsi, now build ARC name of IntermediateController
|
||
// (i.e. the intervening controllers, or everything above ScsiAdapter)
|
||
// start with null, and build string one controller at a time as we
|
||
// return up the recursively called routine.
|
||
//
|
||
|
||
IntermediateController = "\0";
|
||
|
||
return (STATUS_SUCCESS);
|
||
}
|
||
|
||
//
|
||
// Found ScsiAdapter, but wrong scsi id or Lun info doesn't match,
|
||
// (ignore other ZwOpenKey errors &) keep looking...
|
||
//
|
||
|
||
}
|
||
|
||
else if (!_wcsicmp(pControllerKeyInformation->Name, L"MultifunctionAdapter") ||
|
||
!_wcsicmp(pControllerKeyInformation->Name, L"EisaAdapter")) {
|
||
|
||
//
|
||
// This is a valid controller that may have ScsiAdapter beneath it.
|
||
// Open controller & walk controller's subkeys: 0, 1, 2, etc....
|
||
//
|
||
|
||
RtlInitUnicodeString (unicodeString, pControllerKeyInformation->Name);
|
||
|
||
INIT_OPEN_KEY (unicodeString, KeyHandle, &controllerHandle);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
DebugPrint ((2, "FindScsiAdapter: ZwOpenKey got status = %x \n", status));
|
||
ZwClose (controllerHandle);
|
||
return (status);
|
||
}
|
||
|
||
|
||
|
||
for (controllerNumberIndex = 0; TRUE; controllerNumberIndex++) {
|
||
|
||
RtlZeroMemory(numberKeyBuffer, sizeof(numberKeyBuffer));
|
||
|
||
pControllerNumberKeyInformation = (PKEY_BASIC_INFORMATION) numberKeyBuffer;
|
||
|
||
status = ZwEnumerateKey(
|
||
controllerHandle,
|
||
controllerNumberIndex,
|
||
KeyBasicInformation,
|
||
pControllerNumberKeyInformation,
|
||
sizeof(numberKeyBuffer),
|
||
&resultLength
|
||
);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
if (status != STATUS_NO_MORE_ENTRIES) {
|
||
DebugPrint ((2, "FindScsiAdapter: Status %x enumerating key\n", status));
|
||
ZwClose(controllerHandle);
|
||
return (status);
|
||
}
|
||
|
||
ZwClose(controllerHandle);
|
||
|
||
break; // next controller
|
||
}
|
||
|
||
DebugPrint ((3, "FindScsiAdapter: Found Adapter #=%S\n", pControllerNumberKeyInformation->Name));
|
||
|
||
validControllerNumber = TRUE;
|
||
|
||
for (index = 0; index < pControllerNumberKeyInformation->NameLength / 2; index++) {
|
||
|
||
if (!isxdigit(pControllerNumberKeyInformation->Name[index])) {
|
||
validControllerNumber = FALSE;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if (validControllerNumber) {
|
||
|
||
//
|
||
// Found valid controller and controller number: check children for scsi.
|
||
//
|
||
|
||
RtlInitUnicodeString (unicodeString, pControllerNumberKeyInformation->Name);
|
||
|
||
INIT_OPEN_KEY (unicodeString, controllerHandle, &controllerNumberHandle);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
DebugPrint ((2, "FindScsiAdapter: Status %x opening controller number key\n", status));
|
||
ZwClose(controllerNumberHandle);
|
||
ZwClose(controllerHandle);
|
||
return (status);
|
||
}
|
||
|
||
RtlZeroMemory(lowerController, sizeof(lowerController));
|
||
|
||
status = FindScsiAdapter(
|
||
controllerNumberHandle,
|
||
ScsiUnicodeString,
|
||
&lowerController[0]
|
||
);
|
||
|
||
ZwClose(controllerNumberHandle);
|
||
|
||
if (NT_SUCCESS(status)) {
|
||
|
||
//
|
||
// SUCCESS!
|
||
//
|
||
// Scsi adapter DOES exist under this node,
|
||
// prepend Arc Name for the current adapter to whatever was returned
|
||
// by other calls to this routine.
|
||
//
|
||
|
||
if (!_wcsicmp(pControllerKeyInformation->Name, L"MultifunctionAdapter")) {
|
||
sprintf(IntermediateController, "multi(0)%s", lowerController);
|
||
} else {
|
||
sprintf(IntermediateController, "eisa(0)%s", lowerController);
|
||
}
|
||
|
||
ZwClose(controllerHandle);
|
||
|
||
return(STATUS_SUCCESS);
|
||
}
|
||
|
||
else if (status != STATUS_OBJECT_PATH_NOT_FOUND) {
|
||
ZwClose(controllerHandle);
|
||
return(status);
|
||
}
|
||
|
||
//
|
||
// Scsi not found under this controller number, check next one
|
||
//
|
||
|
||
} // if validControllerNumber
|
||
|
||
} // for controllerNumberIndex
|
||
|
||
|
||
|
||
//
|
||
// ScsiAdapter not found under this controller
|
||
//
|
||
|
||
ZwClose(controllerHandle);
|
||
|
||
} // else if valid subkey (i.e., scsi, multi, eisa)
|
||
|
||
} // for controllerIndex
|
||
|
||
//
|
||
// ScsiAdapter not found under key we were called with
|
||
//
|
||
|
||
IntermediateController = "\0";
|
||
#endif
|
||
return (STATUS_OBJECT_PATH_NOT_FOUND);
|
||
}
|