⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 findscsi.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 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 <ntddk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <include/class2.h>
#include <stdio.h>

//#define NDEBUG
#include <debug.h>

NTSTATUS
STDCALL
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
STDCALL
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);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -